不管是一个condition 两个condition 三个condition 都需要一个标志未来判定
案例1的 flag
案例2的 count ==100 count ==0
案例3的 number =1
1 Lock和Condition简介:
Lock 替代 synchronized
比传统线程模型synchronized更加面向对象,
能够适应 "hand-over-hand" 或 "chain locking":获取节点 A 的锁,然后再获取节点 B 的锁,然后释放 A 并获取 C,然后释放 B 并获取 D,这种灵活的锁机制;
Condition 功能类似于object.wait() 和 notify()
Condition的特点:
以前的方式只能有一个等待队列,在实际应用时可能需要多个,比如读和写。
为了这个灵活性,创建多个condition,
互斥保证在某个时刻只有一个线程访问临界区(lock自己完成),
等待队列负责保存被阻塞的线程(condition完成)。
2 lock+condition案例一,生产者消费者代码(单队列 只需要一个condition):
package thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * * @author zm * 执行结果: 第 0 次执行B 第 1 次执行A 第 1 次执行B 第 2 次执行A 第 2 次执行B 第 3 次执行A 第 3 次执行B 第 4 次执行A 第 4 次执行B 第 5 次执行A 第 5 次执行B 第 6 次执行A 第 6 次执行B 第 7 次执行A 第 7 次执行B 第 8 次执行A 第 8 次执行B 第 9 次执行A 第 9 次执行B * * * 为什么需要使用condition呢?简单一句话,lock更灵活。以前的方式只能有一个等待队列,在实际应用时可能需要多个,比如读和写。为了这个灵活性,lock将同步互斥控制和等待队列分离开来, * 互斥保证在某个时刻只有一个线程访问临界区(lock自己完成),等待队列负责保存被阻塞的线程(condition完成)。 * * 案例1:我生产一个面包,就通知顾客来拿 * condition能够实现实际业务中 多等待队列交互模式, 传统 wait() notify()只能实现一个等待队列; * 下面案例是使用 conditon实现 一个等待队列模式 取代 传统 wait() notify()的写法( 生产者-消费者, 我生产一个面包,就通知顾客来拿, 只有一个队列) * * * 案例2: 两队人,一队不停像100个篮子生产面包,一队不停从篮子拿走面包(阻塞队列) * * 如果是我不停的生产面包放在篮子里,我不管消费者拿面包, notfull队列(篮子还没存放满面包队列 有自己独自的wait nodify) * 而消费者不停的去从篮子里拿面包,而不管生产者生产了多少, notempty队列(篮子面包还没空队列 有自己独自的wait nodify) * 那么这就是两个队列, * notfull队列, 只管像篮子里放面包,当100个篮子满的时,放面包动作处于等待 * notempty队列,只管从篮子里拿面包,当100个篮子空的时,存面包动作处于等待 * 此时需要使用同一个lock的两个condition来实现第二个案例 * */ public class CommunicateWithConditionThread { // A 执行一次 B 执行一次 一共执行20次 public static void main(String[] args) { final Out out = new Out(); // out对象就是同一个门栓 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0; i<10; i++){ out.printA(i); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0; i<10; i++){ out.printB(i); } } }).start(); } } class Out { // public boolean flag = true; Lock lock = new ReentrantLock(); Condition conditon = lock.newCondition(); // 使用一个conditon, 模拟一组等待队列 public void printA(int i){ lock.lock(); try{ while(!flag){// 当flag = false时,线程执行此业务方法时等待 try { conditon.await();// 门栓等待 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("第 " + i + " 次执行A,生产了面包"); // 否则直接执行业务方法 flag = false; // 更改标志位 conditon.signal(); // 使用方法 不要使用错了 }finally{ lock.unlock(); } } public void printB(int j){ lock.lock(); try{ while(flag) {// 当flag = true时, 线程执行此业务方法时等待 try { conditon.await();// 门栓等待 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("第 " + j + " 次执行B,消费了面包"); flag = true; // 更改标志位 conditon.signal(); // }finally{ lock.unlock(); } } }
3 lock+condition案例二,多队列等待代码(阻塞队列 需要两个condition):
* 案例2: 两队人,一对不停像100个篮子生产面包,一对不停从篮子拿走面包(阻塞队列) * * 如果是我不停的生产面包放在篮子里,我不管消费者拿面包, notfull队列(篮子还没存放满面包队列 有自己独自的wait nodify) * 而消费者不停的去从篮子里拿面包,而不管生产者生产了多少, notempty队列(篮子面包还没空队列 有自己独自的wait nodify) * 那么这就是两个队列, * notfull队列, 只管像篮子里放面包,当100个篮子满的时,放面包动作处于等待 * notempty队列,只管从篮子里拿面包,当100个篮子空的时,存面包动作处于等待 * 此时需要使用同一个lock的两个condition来实现第二个案例 * 注意: count表示当前面包真实个数(生产一个 同时下个线程拿走一个 那么count = 0) * items: 存放面包篮子 * putptr, 生产面包后 存放在篮子的角标, * takeptr,取走面包时,面包所在篮子的角标 class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); // 生产队列 final Condition notEmpty = lock.newCondition(); // 消费队列 final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); // 生产面包上锁 try { while (count == items.length) // 当生产队列并发大到突然生产了100个面包时,生产队列等待 notFull.await(); // 否则执行生产面包操作, 不断向数组下一个单元格内放新面包 items[putptr] = x; if (++putptr == items.length) putptr = 0;// 当存放的面包到达数组最后位置时,篮子存放面包位置又从0开始 ++count; // 记录面包个数 notEmpty.signal();// 生产了面包,就立即通知消费队列去取走面包 } finally { lock.unlock();// 生产面包完成 解锁 让下个生产执行 } } public Object take() throws InterruptedException { lock.lock();// 取面包上锁 try { while (count == 0) // 当消费队列消费并发过大,或者刚开始没生产出面包时,消费队列等待 notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0;// 当取走面包到篮子最后一个位置时,重置,再从篮子最开始位置取面包 --count;// 记录面包个数 取走一次面包 个数减一 notFull.signal(); // 取走面包, 立即通知生产队列生产面包 return x; } finally { lock.unlock(); // 取面包完成 解锁 让下个取面包动作执行 } } }
3 lock+condition案例三,(三队列):
扩展: 产生三个线程 A -->B --> C ---> A 这里需要三个condition
package thread; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 三个队列下: * A循环打印5次, B循环打印5次 , C循环打印5次, A执行完后通知B,B 执行完后通知C, C执行完后通知A, 这种形式循环5次 * @author zm * */ public class ThreeConditionCommunication { /** * @param args */ public static void main(String[] args) { final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=5;i++){ business.sub1(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=5;i++){ business.sub2(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=5;i++){ business.sub3(i); } } } ).start(); } static class Business { Lock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCondition(); Condition condition3 = lock.newCondition(); private int num = 1; public void sub1(int i){ lock.lock(); try{ while(num != 1){ try { condition1.await(); } catch (Exception e) { e.printStackTrace(); } } for(int j=1;j<=5;j++){ System.out.println("sub1 thread sequence of " + j + ",loop of " + i); } num = 2; condition2.signal(); }finally{ lock.unlock(); } } public void sub2(int i){ lock.lock(); try{ while(num != 2){ try { condition2.await(); } catch (Exception e) { e.printStackTrace(); } } for(int j=1;j<=5;j++){ System.out.println("sub2 thread sequence of " + j + ",loop of " + i); } num = 3; condition3.signal(); }finally{ lock.unlock(); } } public void sub3(int i){ lock.lock(); try{ while(num != 3){ try { condition3.await(); } catch (Exception e) { e.printStackTrace(); } } for(int j=1;j<=5;j++){ System.out.println("sub3 thread sequence of " + j + ",loop of " + i); } num = 1; condition1.signal(); }finally{ lock.unlock(); } } } }
脑图:
相关推荐
14 线程——条件Condition 16. 15 线程——Semaphore 16. 16 线程——CountDownLatch 16. 17 线程——Cycli Barrier 16. 18 线程——Exchanger 16. 19 线程——BlockingQueue 第17章 Java...
11.2.1 lock、readwritelock与condition 349 11.2.2 使用executor 357 11.2.3 并行collection简介 370 11.3 重点复习 373 11.4 课后练习 375 chapter12 通用api 377 12.1 日志 378 12.1.1 日志api简介...
Java的ReentrantLock是Java并发编程中非常重要的一个同步机制,它是JDK 5.0引入的并发包`java.util.concurrent.locks`中的一个高级锁,提供了比synchronized更细粒度的控制,同时具备更高的灵活性和性能。...
- **JDK5.0新增类别**:`UncaughtExceptionHandler`处理未捕获异常,`Lock`和`Condition`提供更灵活的锁机制,`BlockingQueue`用于线程间的数据传递,`Callable`和`Future`提供异步计算结果,`Executors`提供线程池...
基于Maxwell设计的经典280W 4025RPM高效率科尔摩根12极39槽TBM无框力矩电机:生产与学习双重应用案例,基于Maxwell设计的经典280W高转速科尔摩根TBM无框力矩电机:7615系列案例解析与应用实践,基于maxwwell设计的经典280W,4025RPM 内转子 科尔摩根 12极39槽 TBM无框力矩电机,7615系列。 该案例可用于生产,或者学习用,(157) ,maxwell设计; 280W; 4025RPM内转子; 科尔摩根; 12极39槽TBM无框力矩电机; 7615系列; 生产/学习用。,基于Maxwell设计,高功率280W 12极39槽TBM无框力矩电机:生产与学习双用途案例
基于碳交易的微网优化模型的Matlab设计与实现策略分析,基于碳交易的微网优化模型的Matlab设计与实现探讨,考虑碳交易的微网优化模型matlab ,考虑碳交易; 微网优化模型; MATLAB;,基于Matlab的碳交易微网优化模型研究
二级2025模拟试题(答案版)
OpenCV是一个功能强大的计算机视觉库,它提供了多种工具和算法来处理图像和视频数据。在C++中,OpenCV可以用于实现基础的人脸识别功能,包括从摄像头、图片和视频中识别人脸,以及通过PCA(主成分分析)提取图像轮廓。以下是对本资源大体的介绍: 1. 从摄像头中识别人脸:通过使用OpenCV的Haar特征分类器,我们可以实时从摄像头捕获的视频流中检测人脸。这个过程涉及到将视频帧转换为灰度图像,然后使用预训练的Haar级联分类器来识别人脸区域。 2. 从视频中识别出所有人脸和人眼:在视频流中,除了检测人脸,我们还可以进一步识别人眼。这通常涉及到使用额外的Haar级联分类器来定位人眼区域,从而实现对人脸特征的更细致分析。 3. 从图片中检测出人脸:对于静态图片,OpenCV同样能够检测人脸。通过加载图片,转换为灰度图,然后应用Haar级联分类器,我们可以在图片中标记出人脸的位置。 4. PCA提取图像轮廓:PCA是一种统计方法,用于分析和解释数据中的模式。在图像处理中,PCA可以用来提取图像的主要轮廓特征,这对于人脸识别技术中的面部特征提取尤
麻雀搜索算法(SSA)自适应t分布改进版:卓越性能与优化代码注释,适合深度学习。,自适应t分布改进麻雀搜索算法(TSSA)——卓越的学习样本,优化效果出众,麻雀搜索算法(SSA)改进——采用自适应t分布改进麻雀位置(TSSA),优化后明显要优于基础SSA(代码基本每一步都有注释,代码质量极高,非常适合学习) ,TSSA(自适应t分布麻雀位置算法);注释详尽;高质量代码;适合学习;算法改进结果优异;TSSA相比基础SSA。,自适应T分布优化麻雀搜索算法:代码详解与学习首选(TSSA改进版)
锂电池主动均衡Simulink仿真研究:多种均衡策略与电路架构的深度探讨,锂电池主动均衡与多种均衡策略的Simulink仿真研究:buckboost拓扑及多层次电路分析,锂电池主动均衡simulink仿真 四节电池 基于buckboost(升降压)拓扑 (还有传统电感均衡+开关电容均衡+双向反激均衡+双层准谐振均衡+环形均衡器+cuk+耦合电感)被动均衡电阻式均衡 、分层架构式均衡以及分层式电路均衡,多层次电路,充放电。 ,核心关键词: 锂电池; 主动均衡; Simulink仿真; 四节电池; BuckBoost拓扑; 传统电感均衡; 开关电容均衡; 双向反激均衡; 双层准谐振均衡; 环形均衡器; CUK均衡; 耦合电感均衡; 被动均衡; 电阻式均衡; 分层架构式均衡; 多层次电路; 充放电。,锂电池均衡策略研究:Simulink仿真下的多拓扑主动与被动均衡技术
S7-1500和分布式外围系统ET200MP模块数据
内置式永磁同步电机无位置传感器模型:基于滑膜观测器和MTPA技术的深度探究,内置式永磁同步电机基于滑膜观测器和MTPA的无位置传感器模型研究,基于滑膜观测器和MTPA的内置式永磁同步电机无位置传感器模型 ,基于滑膜观测器;MTPA;内置式永磁同步电机;无位置传感器模型,基于滑膜观测与MTPA算法的永磁同步电机无位置传感器模型
centos7操作系统下安装docker,及docker常用命令、在docker中运行nginx示例,包括 1.设置yum的仓库 2.安装 Docker Engine-Community 3.docker使用 4.查看docker进程是否启动成功 5.docker常用命令及nginx示例 6.常见问题
给曙光服务器安装windows2012r2时候找不到磁盘,问厂家工程师要的raid卡驱动,内含主流大多数品牌raid卡驱动
数学建模相关主题资源2
西门子四轴卧式加工中心后处理系统:828D至840D支持,四轴联动制造解决方案,图档处理与试看程序一应俱全。,西门子四轴卧加后处理系统:支持828D至840D系统,四轴联动高精度制造解决方案,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与经典文献参考,MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与文献参考,MATLAB代码:基于列约束生成法CCG的两阶段问题求解 关键词:两阶段鲁棒 列约束生成法 CCG算法 参考文档:《Solving two-stage robust optimization problems using a column-and-constraint generation method》 仿真平台:MATLAB YALMIP+CPLEX 主要内容:代码构建了两阶段鲁棒优化模型,并用文档中的相对简单的算例,进行CCG算法的验证,此篇文献是CCG算法或者列约束生成算法的入门级文献,其经典程度不言而喻,几乎每个搞CCG的两阶段鲁棒的人都绕不过此篇文献 ,两阶段鲁棒;列约束生成法;CCG算法;MATLAB;YALMIP+CPLEX;入门级文献。,MATLAB代码实现:基于两阶段鲁棒与列约束生成法CCG的算法验证研究
“生热研究的全面解读:探究参数已配置的Comsol模型中的18650圆柱锂电池表现”,探究已配置参数的COMSOL模型下的锂电池生热现象:18650圆柱锂电池模拟分析,出一个18650圆柱锂电池comsol模型 参数已配置,生热研究 ,出模型; 18650圆柱锂电池; comsol模型; 参数配置; 生热研究,构建18650电池的COMSOL热研究模型
移动端多端运行的知识付费管理系统源码,TP6+Layui+MySQL后端支持,功能丰富,涵盖直播、点播、管理全功能及礼物互动,基于UniApp跨平台开发的移动端知识付费管理系统源码:多端互通、全功能齐备、后端采用TP6与PHP及Layui前端,搭载MySQL数据库与直播、点播、管理、礼物等功能的强大整合。,知识付费管理系统源码,移动端uniApp开发,app h5 小程序一套代码多端运行,后端php(tp6)+layui+MySQL,功能齐全,直播,点播,管理,礼物等等功能应有尽有 ,知识付费;管理系统源码;移动端uniApp开发;多端运行;后端php(tp6);layui;MySQL;直播点播;管理功能;礼物功能,知识付费管理平台:全功能多端运行系统源码(PHP+Layui+MySQL)
基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,Python+Django+Mysql个性化图书推荐系统 图书在线推荐系统 基于用户、项目、内容的协同过滤推荐算法。 帮远程安装部署 一、项目简介 1、开发工具和实现技术 Python3.8,Django4,mysql8,navicat数据库管理工具,html页面,javascript脚本,jquery脚本,bootstrap前端框架,layer弹窗组件、webuploader文件上传组件等。 2、项目功能 前台用户包含:注册、登录、注销、浏览图书、搜索图书、信息修改、密码修改、兴趣喜好标签、图书评分、图书收藏、图书评论、热点推荐、个性化推荐图书等功能; 后台管理员包含:用户管理、图书管理、图书类型管理、评分管理、收藏管理、评论管理、兴趣喜好标签管理、权限管理等。 个性化推荐功能: 无论是否登录,在前台首页展示热点推荐(根据图书被收藏数量降序推荐)。 登录用户,在前台首页展示个性化推荐