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();
    }
}
相关推荐
学习中.........1 小时前
JVM 垃圾回收核心技术、演进全景与生产调优规范
java·jvm·测试工具
小小编程路1 小时前
C++类作用域
java·jvm·c++
FlyWIHTSKY1 小时前
Next中引入 Ant Design (antd)的配置
开发语言·前端·javascript
小江的记录本1 小时前
【Java并发编程】锁机制:volatile:JMM内存模型、可见性/禁止指令重排、内存屏障、单例模式中的应用(附《思维导图》+《面试高频考点清单》)
java·后端·python·mysql·单例模式·面试·职场和发展
zandy10111 小时前
2026嵌入式BI PaaS平台技术剖析与实现指南
java·运维·paas
csdn小瓯1 小时前
前端工程化:React + TypeScript + Tailwind CSS 的组件化实践
开发语言·人工智能·python
hef2881 小时前
R包grafify:简单操作实现高效统计绘图
开发语言·python·r语言
这是谁的博客?1 小时前
Python 异步编程核心原理与实践深度解析
java·网络·python·协程·asyncio·异步编程
曹牧1 小时前
VS:焦点上移
开发语言