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();
    }
}
相关推荐
程序喵大人14 小时前
【C++进阶】STL容器与迭代器 - 01 STL 容器先解决元素放在哪里
开发语言·c++·stl
cui_ruicheng14 小时前
Python从入门到实战(十六):多进程编程
开发语言·python
Jelena1577958579215 小时前
电商运营分析数据比价接口实战:多平台价格监控与智能决策系统
java·大数据·数据库
wdfk_prog16 小时前
嵌入式面试真题第 15 题:不可恢复异常后的通用崩溃快照、调用栈保存与离线分析架构
linux·开发语言·面试·架构
晴空了无痕16 小时前
从 Go 基础到 K8s:一条可落地的 Go 服务端成长路线
开发语言·后端·golang·kubernetes
神明不懂浪漫16 小时前
【第五章】Java中的继承与多态
java·开发语言
神州世通17 小时前
解密企业通信安全防线:Avaya Aura 三层安全架构深度解析
开发语言·php
AC赳赳老秦18 小时前
企业工商公开信息采集分析:OpenClaw 批量查询企业工商信息,生成企业画像报告
大数据·开发语言·python·自动化·php·deepseek·openclaw
AI多Agent协作实战派18 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit18 小时前
Java+Ai+vue
java·spring·maven