Java实现线程间的通讯--使用synchronized关键字和JUC方式实现

Java实现线程间的通讯--使用synchronized关键字和JUC方式实现

即比较经典的生产者和消费者问题,生产者在资源为0时进行生产;在资源不为0时,消费者进行消费,生产者和消费者交替执行。多线程的运行由CPU分配执行的,要交替执行,也就是实现

--

当资源为0时,如果消费者获取执行权,则等待并唤醒生产者生产;如果资源不为0,则消费者消费后,再释放锁唤醒生产者生产。

同样的

当资源不为0时,如果生产者获取执行权,则等待并唤醒消费者进行消费;如果资源为0,则生产者生产后,再释放锁唤醒消费者消费。

使用synchronized关键字实现

技术栈:synchronized + wait() + notifyAll()

实现类

java 复制代码
//生产者和消费者各实现为一个方法
public class SynchronizedCommunication {

	//初始化一个变量,作为操作的同步资源数
    private int count;

    //生产者操作
    public synchronized void add(){
        try{
            //对共同资源判断,当存在资源
            while(count != 0) {
                //则生产线程进入等待状态
                this.wait();
            }
                //生产者生产
                count++;
                //打印一下当前线程及操作的共同资源的值,便于理解
                System.out.println(Thread.currentThread().getName()+"::"+count);
        }catch (InterruptedException e){
            throw new RuntimeException(e);
        }finally {
            //唤醒消费者消费
            this.notifyAll();
        }
    }

    //消费者操作
    public synchronized void subtract(){
        try{
            //对共同资源判断
            while (count == 0){
                //则消费线程进入等待状态
                this.wait();
            }
                //消费者消费
                count--;
                System.out.println(Thread.currentThread().getName()+"::"+count);
        }catch (InterruptedException e){
            throw new RuntimeException(e);
        }finally {
            //唤醒生产者生产
            this.notifyAll();
        }
    }
}

注意:上述代码中判断使用的时while循环,因为如果实例化的线程不止一个生产者和消费者时,判断不止一次,if()语句来进行判断会出现假醒问题,可能操作的共同资源有负数的情况。所以不管线程是在什么情况下被唤醒,都要进行判断,符合要求再进行生产或是消费的动作。

测试类

java 复制代码
//这里创建了四个线程,分别两个生产者,两个消费者;可以看一下,如果在这种情况下,使用if语句来进行判断,可能出现假醒问题
public class SynchronizedCommunicationTest {

    public static void main(String[] args) {
        //实例化共同资源类对象
        SynchronizedCommunication sc = new SynchronizedCommunication();

        //创建生产者线程,匿名内部类实现操作
        Thread t0 = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    sc.add();
                }
            }
        },"生产者A");

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    sc.subtract();
                }
            }
        },"消费者B");

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    sc.add();
                }
            }
        },"生产者C");

        Thread t3 = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    sc.subtract();
                }
            }
        },"消费者D");
        t0.start();
        t1.start();
        t2.start();
        t3.start();
    }
}

JUC方式实现

技术栈:Lock锁接口 + Condition接口

实现类

java 复制代码
            lock.unlock();
        }
    }

    public void subtract(){
        lock.lock();
        try {
            while (count == 0) {
                condition.await();
            }
            System.out.println(Thread.currentThread().getName()+"---"+(--count));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            condition.signalAll();
            lock.unlock();
        }
    }
}

测试类

java 复制代码
public class LockCommunicationTest {
    public static void main(String[] args) {
        LockCommunication lc = new LockCommunication();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    lc.add();
                }
            }
        },"生产者1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    lc.add();
                }
            }
        },"生产者2");
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    lc.subtract();
                }
            }
        },"消费者1");
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    lc.subtract();
                }
            }
        },"消费者2");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
相关推荐
Suxing93 分钟前
C语言基础分享:从“租房”到“拆迁”,C语言动态内存管理
java·数据结构·算法
减瓦4 分钟前
别让 Java 版本选择变成生产事故
java
ikun_文5 分钟前
Java集合框架Collection拓展进阶
java·java ee
SomeB1oody14 分钟前
【RustyML入门】3.8. 正则化与归一化层
开发语言·后端·机器学习·rust·教程
__zRainy__17 分钟前
Node系列 · Node基础:全局变量与全局对象
开发语言·前端·javascript
码匠许师傅18 分钟前
【C++ 面试真题】聊聊 C++ 的虚函数和多态
java·c++·面试
chuan.bai1 小时前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
FlyWIHTSKY1 小时前
idea中集成claude功能
java·ide·人工智能·intellij-idea·cloudera
Java成神之路-1 小时前
Spring AI 统一结构化返回:ChatModel / ChatClient 两种实现方式
java·springaialibaba
鬼手点金1 小时前
Scrapy + Playwright 完整示例(JS 动态渲染网页)
开发语言·javascript·爬虫·python·scrapy·html·json