这个东西,到底是做什么用的呢?上过操作系统课程的童鞋们,一定听过的,生产者和消费者问题

我首先不用这个玩意做一下,简单的生产消费。

消费者,从工厂拿一个东西,出来。运行在线程中的。

/*** * @author JetWang**/
public class Customer {/*** 依赖工厂*/public Factory facrory;public Customer(Factory facrory) {this.facrory = facrory;}public void consum(final int value){new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubfacrory.get(value);}}.start();}
}

生产者类似

public class Produce {/*** 依赖工厂*/public Factory facrory;public Produce(Factory facrory) {this.facrory = facrory;};public void produce(final int value){new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubfacrory.put(value);}}.start();}
}

我们的工厂,使用Lock,保护资源共享,修改我们的实例变量的count属性,通过lock控制,线程并发操作。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*** 仓库类* @author JetWang**/
public class Factory {private int count;//仓库的大小private Lock lock;public Factory() {lock=new ReentrantLock();//可重入锁this.count=0;       // TODO Auto-generated constructor stub}/*** 商品入库*/public void put(int value){try {lock.lock();count+=value;System.out.println(Thread.currentThread().getName() + " put " + value +" ----> the count: " + count); } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{lock.unlock();}       }public void get(int value){try {lock.lock();count-=value;System.out.println(Thread.currentThread().getName() + " get " + value +" ----> the count: " + count); } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{lock.unlock();}       }}

下面这个是我们的测试类:

public class Test {public static void main(String[] args) {// TODO Auto-generated method stubFactory factory=new Factory();//公有的工厂Produce pro=new Produce(factory);Customer cus=new Customer(factory);pro.produce(10);cus.consum(5);pro.produce(20);cus.consum(5);pro.produce(5);cus.consum(35);     }}

Thread-0 put 10 —-> the count: 10
Thread-1 get 5 —-> the count: 5
Thread-4 put 5 —-> the count: 10
Thread-5 get 35 —-> the count: -25
Thread-2 put 20 —-> the count: -5
Thread-3 get 5 —-> the count: -10

看哈我们的结果,最后的结果却是是没得错误,很好的完成了工作,是不是呢?但是仓库怎么可能为负数的呢?没有很好的控制吧!消费者在消费的时候我们不可能仓库没得东西都可以拿走吧!这个不符合逻辑

这个就是Condition (条件使用的时候啦,信号)

Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的wait(),notify(),notifyAll()方法是和”同步锁”(synchronized关键字)捆绑使用的;而Condition是需要与”互斥锁”/”共享锁”捆绑使用的。

条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。

Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其newCondition() 方法

下面为我们改进的工厂类

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Factory2 {private int count;//仓库的大小private Lock lock;private Condition fullCondiction;//满的信号private Condition emptyCondiction;//空的信号private int capity;public Factory2() {lock=new ReentrantLock();this.count=0;this.capity=15;fullCondiction=lock.newCondition();emptyCondiction=lock.newCondition();}public void get(int value){lock.lock();try {int left=value;while(left>0){while(count<=0){emptyCondiction.await();}int dec=count<left?count:left;count-=dec;left-=dec;System.out.println(Thread.currentThread().getName() + "----要消费的数量:" + value +";"+ ";实际消费的数量: " + dec + ";"+ ";仓库现存数量:" + count + ";;有多少件商品没有消费:" + left);  //没有满的信号fullCondiction.signal();            }} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{lock.unlock();}}public void put(int value){lock.lock();try {int left=value;while(count>=capity){fullCondiction.await();}int in=this.count+left>this.capity?this.capity-count:left;count+=in;left-=in;System.out.println(Thread.currentThread().getName()+ "----要入库数量: " + value +";;实际入库数量:" + in + ";;仓库货物数量:" + count + ";;没有入库数量:" + left);  //仓库有东西,通知消费emptyCondiction.signal();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{lock.unlock();}}
}

Test

public class Test {public static void main(String[] args) {// TODO Auto-generated method stubFactory2 factory=new Factory2();//公有的工厂Produce pro=new Produce(factory);Customer cus=new Customer(factory);pro.produce(10);cus.consum(5);pro.produce(20);cus.consum(5);pro.produce(5);cus.consum(35);     }}

结果:
Thread-0—-要入库数量: 10;;实际入库数量:10;;仓库货物数量:10;;没有入库数量:0
Thread-1—-要消费的数量:5;;实际消费的数量: 5;;仓库现存数量:5;;有多少件商品没有消费:0
Thread-3—-要消费的数量:5;;实际消费的数量: 5;;仓库现存数量:0;;有多少件商品没有消费:0
Thread-4—-要入库数量: 5;;实际入库数量:5;;仓库货物数量:5;;没有入库数量:0
Thread-2—-要入库数量: 20;;实际入库数量:10;;仓库货物数量:15;;没有入库数量:10
Thread-5—-要消费的数量:35;;实际消费的数量: 15;;仓库现存数量:0;;有多少件商品没有消费:20
没有错误哦~
在Condition中,用await()替换wait(),用signal()替换 notify(),用signalAll()替换notifyAll(),对于我们以前使用传统的Object方法,Condition都能够给予实现。 在线程之间进行同步~

码农小汪-Java Condition相关推荐

  1. 码农小汪-设计模式之-Builder模式

    建造者模式 将一个复杂的对象的构建与它的表示分离,使得同样构建的过程中可以创建不同的表示.这个话语看起来,好累啊!真心很难理解. 下面是它的UML图: 抽象建造者角色(Builder):为创建一个Pr ...

  2. 码农小汪-Hibernate学习8-hibernate关联关系注解表示@OneToMany mappedBy @ManyToMany @JoinTable...

    近期我也是有点郁闷,究竟是程序中处理关联关系.还是直接使用外键处理关联关系呢?这个的说法不一致!程序中处理这样的关联关系的话.自己去维护这样的约束.这样的非常乐观的一种做法!或者是直接在数据库中处理这 ...

  3. 码农小汪-Volatile和Transient

    Volatile: Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看 ...

  4. 码农小汪-设计模式之-命令模式

    大话设计模式的例子讲的非常的好,理解起来也方便!有时候忘了.想到这些特殊的例子感觉就是特别爽. 烤羊肉串带来的思考! 路边摊羊肉串: 老板,我这里排的比较先啊,我最先给钱.老板这个没有熟啊.我的是 辣 ...

  5. 码农翻身全年文章精华

    在码农翻身公众号写了一年多, 最大的体会就是:原创真心不易! 每天思考的最大问题就是: 下一篇文章写啥? 在大家的支持和鼓励下,还是坚持了下来,  回头看看走过的路,这一年过得还算充实. 很快就要过年 ...

  6. 码农翻身 各章节链接

    大话编程 我是一个线程 我是一个Java class Javascript: 一个屌丝的逆袭 Java:一个帝国的诞生 JSP:一个装配工的没落 TCP/IP 之 大明王朝的邮差 TCP/IP 之 大 ...

  7. 码农翻身全年文章精华2016

    在码农翻身公众号写了一年多, 最大的体会就是:原创真心不易! 每天思考的最大问题就是: 下一篇文章写啥? 在大家的支持和鼓励下,还是坚持了下来,  回头看看走过的路,这一年过得还算充实. 很快就要过年 ...

  8. 德国码农开发抢厕纸神器,再也不用愁了

    ,点击 欧盟IT那些事 关注我们 公告:因企鹅审核规定,本公众号从<德国IT那些事>更名为<欧盟IT那些事>. 厕纸在手,天下我有! 疫情中由于欧美人民对厕纸的蜜汁喜爱,导致超 ...

  9. 小编带你两图看清北京大厂公司、码农分布——谷歌,微软,百度,腾讯,阿里,滴滴,美团,头条,独角兽

    小编带你两图看清北京大厂公司.码农分布--谷歌,微软,百度,腾讯,阿里,滴滴,美团,头条 ​ 北京一二线大厂公司.码农分布 年关将至,意味着2021年即将过去,2022年即将到来 现在,就是大家开始为 ...

  10. 转行小姐姐的码农之路

    小姐姐20岁后的人生轨迹是 保研直博 -> 退学 -> 码农... 保研退学 要说能保研并不是因为我是学霸.而是因为大学时期本专业方向没人学习,从小家里穷为了奖学金突击学习成习惯了,所以就 ...

最新文章

  1. memset初始化内存
  2. 面试现场:遇到不会回答的问题,如何力挽狂澜 ?
  3. BootStrap的下载及使用方法
  4. 4.4 Triplet 损失-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  5. oracle游标理解,oracle游标的使用方法
  6. RBF:RBF基于近红外光谱的汽油辛烷值含量预测结果对比
  7. 0118互联网新闻 | 抖音成央视春晚独家社交媒体传播平台;石墨任务清单小程序上线...
  8. 20145315 《Java程序设计》实验五实验报告
  9. android 关闭蓝牙打电话功能,Android蓝牙开发【八】hfp接听、挂断电话
  10. 《 追风筝的人 》:“ 为你,千千万万遍 ” ...
  11. AeroFS 开源 SSMP 协议,包含 Java 和 Go 实现
  12. oracle dblink和dataguard,Oracle 建立 DBLINK
  13. python定义变量_Python基础 变量的基本使用
  14. 新乡学院2019计算机报名,新乡学院2019年招生章程
  15. Eclipse / Java代码完成无法正常工作
  16. GTD时间管理(3)---梳理总结
  17. altiumdesigner的基本你操作
  18. hive partition 分区详解一
  19. bbs.FISHC.com//python_文件
  20. ad7606驱动及仿真

热门文章

  1. 解决三星PM981硬盘无法正常安装黑苹果的问题(第四版)
  2. 初二生态系统思维导图_有关初中生态系统的思维导图
  3. 三维空间内点到直线的距离计算公式
  4. 2018通达信l2服务器源码,很后悔购买了通达信L2看盘软件,大家不要再买进这个软件了...
  5. C++函数模板(模板函数)详解
  6. 如何下载ei和sci论文
  7. 软件工程基础知识--需求分析
  8. pycharm格式化的html_pycharm格式化代码 常用快捷键
  9. Android 做服务器NanoHTTPD使用
  10. Javascript特效代码大全(420个)