JUC练习代码-JUC版本实现生产者消费者问题

个人学习JUC代码笔记总集 个人学习的时候对JUC做的笔记,包括所有代码,学习视频是尚硅谷周阳老师的JUC,需要有一定的基础才能看懂,这是个人笔记,不一定适用于所有人,谢谢! 立即下载
public class JUCTest02 {
    public static void main(String[] args) throws InterruptedException {
        Data2 data = new Data2();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "D").start();

    }
}

//判断是否等待,业务,干完活通知
class Data2 {
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public void increment() throws InterruptedException {
        lock.lock();
        try {

            while (number > 0) {
                //等待
                System.out.println(Thread.currentThread().getName() + "wait");
                condition.await();
            }
            number++;

            //通知其他线程,我+1完毕了
            System.out.println(Thread.currentThread().getName() + "执行了+1" + ";number=" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            lock.unlock();
        }


    }

    public void decrement() throws InterruptedException {
        lock.lock();
        try {

            while (number <= 0) {
                //等待
                System.out.println(Thread.currentThread().getName() + "wait");
                condition.await();
            }
            number--;
            //通知其他线程,我+1完毕了
            System.out.println(Thread.currentThread().getName() + "执行了-1" + ";number=" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }


    }
}

编写代码时注意顺序,首先是lock.lock(),然后try 里面包括业务逻辑,最后finally lock.unlock()
Condition也是JUC包下接口,可以通过lock.newCondition()进行实例化。
Condition中await,signal ,signalAll方法,对应Object的wait,notify,notifyAll方法。

上述代码样例打印的部分结果如下所示

A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
Await
B执行了-1;number=0
Bwait

虽然满足0,1输出,但是怎么保证ABCD也是按照顺序打印呢?

其实只要创建多个condition对象,就可以精确等待和唤醒了。如下图代码所示:

public class JUCTest02 {
    public static void main(String[] args) throws InterruptedException {
        Data2 data = new Data2();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.increment1();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.decrement2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.increment3();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    data.decrement4();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "D").start();

    }
}

//判断是否等待,业务,干完活通知
class Data2 {
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();
    Condition condition4 = lock.newCondition();

    public void increment1() throws InterruptedException {
        lock.lock();
        try {

            while (number > 0) {
                //等待
                System.out.println(Thread.currentThread().getName() + "wait");
                condition1.await();
            }
            number++;

            //通知其他线程,我+1完毕了
            System.out.println(Thread.currentThread().getName() + "执行了+1" + ";number=" + number);
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            lock.unlock();
        }


    }

    public void decrement2() throws InterruptedException {
        lock.lock();
        try {

            while (number <= 0) {
                //等待
                System.out.println(Thread.currentThread().getName() + "wait");
                condition2.await();
            }
            number--;
            //通知其他线程,我+1完毕了
            System.out.println(Thread.currentThread().getName() + "执行了-1" + ";number=" + number);
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }


    }

    public void increment3() throws InterruptedException {
        lock.lock();
        try {

            while (number > 0) {
                //等待
                System.out.println(Thread.currentThread().getName() + "wait");
                condition3.await();
            }
            number++;

            //通知其他线程,我+1完毕了
            System.out.println(Thread.currentThread().getName() + "执行了+1" + ";number=" + number);
            condition4.signal();
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            lock.unlock();
        }


    }

    public void decrement4() throws InterruptedException {
        lock.lock();
        try {

            while (number <= 0) {
                //等待
                System.out.println(Thread.currentThread().getName() + "wait");
                condition4.await();
            }
            number--;
            //通知其他线程,我+1完毕了
            System.out.println(Thread.currentThread().getName() + "执行了-1" + ";number=" + number);
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }


    }

部分打印结果,如下所示:

A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
D执行了-1;number=0
Dwait
A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
D执行了-1;number=0
Dwait
A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
D执行了-1;number=0
Dwait
A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
D执行了-1;number=0
Dwait
A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
D执行了-1;number=0
Dwait
A执行了+1;number=1
Await
B执行了-1;number=0
Bwait
C执行了+1;number=1
Cwait
D执行了-1;number=0
Dwait
手把手教你理解特斯拉Model 3的域控制器架构:RBCM如何成为“多面手”? 本文深入解析特斯拉Model 3的域控制器架构,重点介绍右车身域控制器(RBCM)如何整合车身电子系统功能。RBCM作为多任务处理中枢,管理空调系统、尾部电气设备和超声波雷达等关键功能,展现了特斯拉在汽车电子架构上的创新设计。文章详细探讨了RBCM的硬件架构、功能版图及信号网络,揭示其如何通过高性能MCU和智能开关技术实现功能集中与效率提升。 阅读详情

相关推荐

基于python的奥运会历史数据分析【120年】

数据分析实战案例

xff123456_的博客 3338

JUC并发编程

JUC并发编程

weixin_42522705的博客 235

数学建模:相关性分析学习——皮尔逊(pearson)相关系数与斯皮尔曼(spearman)相关系数

相关性分析:求解相关系数并绘制热力图进行对比

weixin_67565775的博客 8万+

JUC习题

练习JUC的题目 语言:Java 来源:LeetCode 打印奇偶数 使用sem比lock要简单一些 class ZeroEvenOdd { private int n; Semaphore zero = new Semaphore(1); Semaphore even = new Semaphore(0); Semaphore odd = new Semaphore(0); volatile int flag = 1; public ZeroEvenOdd

qq_34446716的博客 558

从数字后端角度谈谈occ电路(二)

从图中,我们可以清晰的看出,当scan_en为1时,test mode为1时,经过一系列逻辑单元后,得到clk_sel输出信号为1,同样可推算fast_clk_en = 0,slow_clk_en为1,此时clk_out输出为slow clk,符合我们预期。在该模式下,是使用slow clock进行scan shift,接着我们开始进行推导;从图中,我们根据逻辑运算可以看出,clk_sel输出信号为0,fast clk en为1,此时通过mux选择,clk out即为fast clk;

芯冰乐 358

2、探索谷歌云平台(GCP):入门指南

本文全面介绍了谷歌云平台(GCP)的入门知识,涵盖其全球基础设施、核心服务和使用方法。内容包括GCP区域与可用区结构、创建免费账户、配置计算资源(如GCE虚拟机)、存储类型(PD、Filestore、GCS)、网络架构(VPC)、组织与项目管理、身份访问控制(IAM),以及计算、存储、数据库、大数据和人工智能等各类云服务。文章还提供了资源规划、安全管理和成本控制等实用建议,帮助用户快速上手并高效利用GCP构建可扩展的云解决方案。

uber9的博客 254

JUC练习——线程安全的计数器

当我们在多线程环境下需要共享一个计数器时,确保计数操作的线程安全性是至关重要的。线程安全的计数器能够确保在多个线程同时访问和修改计数器时,不会出现数据不一致或者竞态条件的问题。常见的实现方式包括使用锁机制(如 synchronized 或 ReentrantLock )、使用原子变量(如 AtomicInteger )。着两种方式实现的原理都很简单,代码也比较简单。

深夜无眠的博客 473

联邦学习中的差分隐私保护详解及python实现

随着数据隐私法规(如 GDPR、CCPA)日益严格,传统将数据集中到云端训练模型的方式面临合规与安全风险。联邦学习通过让各客户端保留本地数据,仅共享模型更新,缓解了数据流动带来的隐私风险。但模型更新仍可能泄露个体信息。为进一步保障隐私,可在本地更新中引入差分隐私(DP)机制,通过向梯度或模型更新中注入随机噪声,防止反向推断原始数据citeturn0search9。

闲人编程的博客 1920

Java并发编程JUC-小结

Java并发编程JUC(java.util.concurrent)提供了一些可重用的线程安全组件,这些组件可以帮助我们更容易地实现高效且正确的并发程序。

专注后端开发 419

14 Prompt 的边界:什么时候必须用 RAG 或微调

Prompt 不是万能解法。本文用“改输入、补知识、改模型”这条主线,讲清什么时候继续优化 Prompt,什么时候必须引入 RAG、工具调用或微调,帮助你避免用重技术掩盖轻问题。

老于的笔记的专栏 209

华为OD机试真题 新系统2026-04-08 C++ 实现【直捣黄龙】

小王在玩一款叫做直捣黄龙的小游戏,在该游戏中他需要从入口位置进入敌营,绕过哨兵的层层封锁,达到敌军司令部实施斩首行动。 敌军阵营是一个n*n的矩阵,入口在坐标(0,n/2),敌军司令部在坐标(n-1,n/2),每个 哨兵警戒以自己为中心的9宫格,一旦被哨兵发现则行动失败。

MISAYAONE的博客 261

Java多线程 JUC并发编程 (第二天)

多线程进阶=>JUC并发编程 9、读写锁 ReadWriteLock 代码实现 package com.feimai.test.JUCTest.rw; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLo.

别訆我小内脏的博客 1336

#systemverilog# 之 event region 和 timeslot 仿真调度(三)Verdi 辅助查看

通过今天的学习,我们知道:event region 是event sequence 的全集。我们打开了 event region feature 也就开启了event sequence 的功能。

那么菜的博客 1365

【JUC基础】06. 生产者和消费者问题

学习JUC,就不得不提生产者消费者。生产者消费者模型是一种经典的多线程模型,用于解决生产者和消费者之间的数据交换问题。在生产者消费者模型中,生产者生产数据放入共享的缓冲区中,消费者从缓冲区中取出数据进行消费。在这个过程中,生产者和消费者之间需要保持同步,以避免数据出现错误或重复。今天我们就来说说生产者消费者模型,以及JUC中如何解决该模型的同步问题。

有一只柴犬的专栏 1207

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【JUC基础学习笔记】

JUC基础学习笔记一、JUC概述1. JUC是什么2. 进程与线程3. 并发与并行4. sleep() 和 wait()等方法二、Lock1. Synchronized2. Lock接口与方法3. 两者异同4. Lock接口重要实现类三、线程通信 / 线程同步1. Synchronized同步块2. Lock锁四、线程安全1. 阻塞同步2. 非阻塞同步3. 非同步五、集合的线程安全1. 并发集合 ArrayList2. Vector3. Collections4. JUC.CopyOnWriteList..

sixteen_16的博客 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【JUC学习】——生产者消费者问题

  生产者消费者问题用于很好的解释线程间通信的问题,大致意思可以解释为如果货架上物品为空,则通知生产者开始生产物品,如果货架上的物品满了,就通知消费者进行消费。在JUC中实现主要是通过synchronized和lock实现,对于synchronized,一般采用wait(等待)和notify(唤醒)进行线程的同步通信。在juc并发包下对应的lock方法为await和signal,同时使用资源监视器Condition来进行精准唤醒。 一、Synchronized(wait和notify) 下面看一下第一版的

时光、疏离了记忆づ童话的博客 507

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

JUC生产者消费者问题

juc版本和synchronized版本的区别: juc这里使用锁需要事先在类里面声明锁,然后用锁获取newCondition,使用condition类即可,以下是jdk,api里面写的 例如,假设我们有一个有限的缓冲区,它支持put和take方法。 如果在一个空的缓冲区尝试一个take ,则线程将阻塞直到一个项目可用; 如果put试图在一个完整的缓冲区,那么线程将阻塞,直到空间变得可用。 我们希望在单独的等待集中等待put线程和take线程,以便我们可以在缓冲区中的项目或空间可用的时候使用仅通知单个线程

qq_42388853的博客 190

Juc02_Synchronized、ReentrantLock实现生产者和消费者问题

4456

所得皆惊喜 6044

JUC与生产者消费者

前面一篇文章介绍了生产者消费者模式,这篇来看看JUC包下的哪些类与该模式有关。 生产者消费者模式中有个中间类Channel,对于数据Data起到通道作用,还确保了Producer与Consumer这些线程的协调运行。在前篇文章所举的例子中的Table类担任这个角色,内部是使用数组实现的队列配合synchronized关键字。而在JUC包下提供了BlockingQueue接口及其实现类,它们相当于C...

业精于勤荒于嬉 行成于思毁于随 551

Synchronized 和 JUC实现生产者、消费者问题

Synchronized版本 当只有两个线程的时候, 是没有问题的, 当时线程数量变多后, 就会出现问题 // 示意生产者、消费者问题 public class demo01 { public static void main(String[] args) { data data = new data(); new Thread(() -> { ...

cyt 337

JUC-生产者消费者问题-02

JUC-生产者消费者问题-02 生产者消费者问题 面试的:单例模式,排序算法,生产者消费者问题,死锁 sychronized版本 package com.rongrong.pc; /** 线程之间通信问题,生产者消费者问题,等待唤醒,通知唤醒 线程之间交替进行,A,B操作同一个变量,num=0 A:num+1 B:num-1 */ public class A { public static void main(String[] args) { Data data

rr18758236029的博客 214

JUC并发编程-线程和进程、Synchronized 和 Lock、生产者和消费者问题

什么是JUC、线程和进程、Lock锁、生产者和消费者问题

小孔靠得住的博客 1088

JUC之生产者与消费者问题

一、简介 生产者与消费者问题主要是涉及到线程间通信的问题,以一个简单案例为例,初始没有产品,生产者生产了产品,就要消费者去消费,消费者消费完再让生产者继续生产 二、Synchronized版本 package P_C.Synchronized; public class TestPC { public static void main(String[] args) { Data data = new Data(); new Thread(()->{

OriSu 414

JUC练习代码-Synchronized实现生产者消费者问题

生产者消费者问题,用Synchronized关键字解决方法如下: 两个线程操作同一个对象,一个进行+1操作,一个进行-1操作。 本代码仅用于练习操作,不要直接在生产环境执行。 public class JUCTest01 { public static void main(String[] args) throws InterruptedException { Data data = new Data(); new Thread(()->{

微信公众号:老张聊天,一个为了你能进步操碎心的公众号。 211

狂神JUC——Synchronized版的生产者和消费者问题

package com.company; /** * 消费者和生产者:线程之间的通信问题 * 等待唤醒,通知唤醒 * 不同的线程操作同一个变量 */ public class ProducerAndConsumer { public static void main(String[] args) { Data data = new Data(); //添加线程 new Thread(()->{ for (i

黄坤的博客 1063

02-生产者消费者问题&condition 实现精准唤醒(1)

由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!小编准备了一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!” />由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

2401_83329718的博客 1154
上一篇: JUC练习代码-Synchronized实现生产者消费者问题
下一篇: JUC练习代码-CountDownLatch用法
老张聊天
博客等级 码龄18年 92粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值