1. package com.mozq.thread.producer2;
  2.  
  3. import java.util.concurrent.locks.Condition;
  4. import java.util.concurrent.locks.Lock;
  5. import java.util.concurrent.locks.ReentrantLock;
  6. /**
  7. * 当使用等待时
  8. * 如果用if会造成,线程被唤醒时不管条件是否满足,都会执行任务代码。产生错误。
  9. * 改用while,每次线程被唤醒时会进行条件判断,是否满足。但是产生了死锁问题。
  10. * 1.通过使用notifyAll而不是notify方法来解决死锁。
  11. * 单生产者和单消费者不会因使用while发生死锁,因为,线程池中只有 一个另一方的线程,notify方法必然会唤醒另一方的线程。
  12. * 多生产者和多消费者的等待集中有生产方和消费方的线程,notify方法可能会唤醒本方线程而不是另一方,造成 死锁。
  13. *
  14. * Condition对象可以为表示锁的一个等待集,一个锁可以产生多个Condition对象也就是等待集。并对它们分别进行操作。
  15. * 针对多生产者和多消费者,我们可以分别为生产者和消费者创建一个等待集,并在唤醒时,调用另一方等待集的通知,确保唤醒的是另一方线程。避免了死锁。
  16. *
  17. * @author jie
  18. *
  19. */
  20. class Resource{
  21. private String name = null;
  22. private int count = 0;
  23. private boolean set = false;
  24. private Lock lock = new ReentrantLock();
  25. private Condition producer = lock.newCondition();
  26. private Condition consumer = lock.newCondition();
  27.  
  28. public void set(String name) {
  29. lock.lock();
  30. try {
  31. //如果已经存在资源,等待
  32. while(set) {
  33. try {
  34. producer.await();
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. //没有资源就创建
  40. count++;
  41. this.name = name + count;
  42. System.out.println(Thread.currentThread().getName() + "生产。"+ this.name);
  43. set = true;
  44. //同时消费者消费
  45. consumer.signal();
  46. }finally {
  47. lock.unlock();
  48. }
  49. }
  50.  
  51. public void out() {
  52. lock.lock();
  53. try {
  54. //如果没有产品,等待
  55. while(!set) {
  56. try {
  57. consumer.await();
  58. } catch (InterruptedException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. //有就消费
  63. System.out.println(Thread.currentThread().getName() + "消费。。。。。"+ this.name);
  64. set = false;
  65. //通知生产者生产
  66. producer.signal();
  67. } finally {
  68. lock.unlock();
  69. }
  70. }
  71. }
  72.  
  73. class Input implements Runnable{
  74. private Resource r;
  75. public Input(Resource r) {
  76. this.r = r;
  77. }
  78.  
  79. @Override
  80. public void run() {
  81. while(true) {
  82. r.set("烤鸡");
  83. }
  84. }
  85.  
  86. }
  87. class Output implements Runnable{
  88. private Resource r;
  89. public Output(Resource r) {
  90. this.r = r;
  91. }
  92.  
  93. @Override
  94. public void run() {
  95. while(true) {
  96. r.out();
  97. }
  98. }
  99.  
  100. }
  101.  
  102. public class ProducerConsumerDemo {
  103. public static void main(String[] args) {
  104. //创建资源
  105. Resource r = new Resource();
  106. //创建任务
  107. Input in = new Input(r);
  108. Output out = new Output(r);
  109. //创建线程
  110. Thread t0 = new Thread(in);
  111. Thread t1 = new Thread(in);
  112. Thread t2 = new Thread(out);
  113. Thread t3 = new Thread(out);
  114. //开启线程
  115. t0.start();
  116. t1.start();
  117. t2.start();
  118. t3.start();
  119. }
  120. }

生产者消费者 java.util.concurrent.lock包的更多相关文章

  1. Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法

    1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...

  2. Java并发—java.util.concurrent.locks包

    一.synchronized的缺陷 synchronized是java中的一个关键字,也就是说是Java语言内置的特性.那么为什么会出现Lock呢? 如果一个代码块被synchronized修饰了,当 ...

  3. JDK源码学习之 java.util.concurrent.automic包

    一.概述 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CP ...

  4. Java并发—原子类,java.util.concurrent.atomic包(转载)

    原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...

  5. java.util.concurrent.atomic 包详解

    Atomic包的作用: 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心: Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作 关于CAS compar ...

  6. 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包

    Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...

  7. java.util.concurrent包

    在JavaSE5中,JUC(java.util.concurrent)包出现了 在java.util.concurrent包及其子包中,有了很多好玩的新东西: 1.执行器的概念和线程池的实现.Exec ...

  8. java.util.concurrent.atomic 类包详解

    java.util.concurrent包分成了三个部分,分别是java.util.concurrent.java.util.concurrent.atomic和java.util.concurren ...

  9. 并发之java.util.concurrent.atomic原子操作类包

    15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...

随机推荐

  1. Ubuntu增加Swap分区大小

    参考:http://blog.csdn.net/mznewfacer/article/details/7334592 以下摘自上述地址内容,并做了点小修改: 1.首先用命令free查看系统内 Swap ...

  2. escape() VS encodeURI() VS encodeURIComponent()

    JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...

  3. poj3349 Snowflake Snow Snowflakes —— 哈希表

    题目链接:http://poj.org/problem?id=3349 题意:雪花有6个瓣,有n个雪花,输入每个雪花的瓣长,判断是否有一模一样的雪花(通过旋转或翻转最终一样,即瓣长对应相等).如果前面 ...

  4. GDP与股市市值

    巴菲特提出一个判断市场估值高低的原则:市场总市值与GDP之比的高低,反映了市场投资机会和风险度.如果所有上市公司总市值占GDP的比率在70%-80%之间,则买入股票长期而言可能会让投资者有相当不错的报 ...

  5. centos 安装配置kettle

    安装JDK1.8: step1 下载JDK1.8 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133 ...

  6. ubuntu 下编译安装ceph

    git clone --recursive https://github.com/ceph/ceph.git  cd ceph/  sudo apt-get install libtool   sud ...

  7. 并不对劲的BJOI2019

    一些感想 现实并非游戏,并不支持反复刷关 猎人和防御工事一起被老山龙摧毁了: 猎人惨死雨中,结云村永无放晴之日: 猎人被狂龙病毒侵蚀,天空山上黑蚀龙泛滥. 好像这才是怪物猎人系列的真实结局呢 day ...

  8. juery的跨域请求2

    时间过得好快,又被拉回js战场时, 跨域问题这个伤疤又开疼了. 好在,有jquery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅了相关资料,算是解决了 ...

  9. 「IOI1998」「LuoguP4342」Polygon(区间dp

    P4342 [IOI1998]Polygon - 洛谷 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符 ...

  10. 安装ubuntu+Windows双系统, Windows启动项消失

    这里主要介绍grub分区损坏的问题: 首先介绍最简单的方法, 不确定能不能成功, 但是最好先用此方法, 毕竟最简单如果解决就不用下一个方法了. 1. (1)用U盘做一个ubuntu的镜像, 开机进入U ...