转:http://blog.csdn.net/a352193394/article/details/39454157

我们在多线程开发中,可能会出现这种情况。就是一个线程需要另外一个线程满足某某条件才能继续运行,或者需

要其他线程满足好几个条件才能运行,对于这样的多条件的多线程并发,我们如何控制好各个线程之间的关系,使他们

能很好的处理冲突不至于相互出现问题呢,下面我们来介绍一下Java提供的Condition这个接口,这个接口很好的实现了

这种需求。

对于这个问题最经典的例子就是生产者消费者模型,生产者当缓冲区满的时候不生产商品知道缓冲区有空余,消费

者当缓冲区为0 的时候不拿商品,直到生产者向缓冲区放入商品,下面我们使用Conditon这个接口来实现这样的需求。

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. import java.util.concurrent.locks.Condition;
  4. import java.util.concurrent.locks.Lock;
  5. import java.util.concurrent.locks.ReentrantLock;
  6. /**
  7. * 有时候线程取得lock后需要在一定条件下才能做某些工作,比如说经典的Producer和Consumer问题。
  8. * 在Java 5.0以前,这种功能是由Object类的wait(), notify()和notifyAll()等方法实现的,
  9. * 在5.0里面,这些功能集中到了Condition这个接口来实现。
  10. */
  11. public class ConditionTest {
  12. /**
  13. * 篮子程序,这里为了简化问题,篮子中最多只能有一个苹果。
  14. * Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定,
  15. * 等到Producer往篮子里放了苹果后再去拿来吃。而Producer必须等到篮子空了才能往里放苹果,
  16. * 否则它也需要暂时解锁等Consumer把苹果吃了才能往篮子里放苹果。
  17. */
  18. public static class Basket {
  19. // 锁
  20. Lock lock = new ReentrantLock();
  21. //  根据锁产生Condition对象
  22. Condition produced = lock.newCondition();
  23. Condition consumed = lock.newCondition();
  24. // 篮子中的苹果数,最多为1
  25. int num = 0;
  26. /**
  27. * 生产苹果,往篮子里放
  28. * @throws InterruptedException
  29. */
  30. public void produce() throws InterruptedException {
  31. // 获得锁
  32. lock.lock();
  33. System.out.println("Producer get a lock...");
  34. try {
  35. // 判断是否满足生产条件
  36. while (num == 1) {
  37. // 如果有苹果,则不生产,放弃锁,进入睡眠
  38. // 等待消费者消费
  39. System.out.println("Producer sleep...");
  40. consumed.await();
  41. System.out.println("Producer awaked...");
  42. }
  43. /*生产苹果*/
  44. Thread.sleep(500);
  45. System.out.println("Producer produced an Apple.");
  46. num = 1;
  47. // 通知等待produced Condition的线程
  48. produced.signal();
  49. } finally {
  50. lock.unlock();
  51. }
  52. }
  53. /**
  54. * 消费苹果,从篮子中取
  55. * @throws InterruptedException
  56. */
  57. public void consume() throws InterruptedException {
  58. // 获得锁
  59. lock.lock();
  60. System.out.println("Consumer get a lock...");
  61. try {
  62. // 判断是否满足消费条件
  63. while (num == 0) {
  64. // 如果没有苹果,无法消费,则放弃锁,进入睡眠
  65. // 等待生产者生产苹果
  66. System.out.println("Consumer sleep...");
  67. produced.await();
  68. System.out.println("Consumer awaked...");
  69. }
  70. /*吃苹果*/
  71. Thread.sleep(500);
  72. System.out.println("Consumer consumed an Apple.");
  73. num = 0;
  74. // 发信号唤醒某个等待consumed Condition的线程
  75. consumed.signal();
  76. } finally {
  77. lock.unlock();
  78. }
  79. }
  80. }
  81. /**
  82. * 测试Basket程序
  83. */
  84. public static void testBasket() throws Exception {
  85. final Basket basket = new Basket();
  86. //  定义一个producer
  87. Runnable producer = new Runnable() {
  88. public void run() {
  89. try {
  90. basket.produce();
  91. } catch (InterruptedException ex) {
  92. ex.printStackTrace();
  93. }
  94. }
  95. };
  96. // 定义一个consumer
  97. Runnable consumer = new Runnable() {
  98. public void run() {
  99. try {
  100. basket.consume();
  101. } catch (InterruptedException ex) {
  102. ex.printStackTrace();
  103. }
  104. }
  105. };
  106. //  各产生3个consumer和producer
  107. ExecutorService service = Executors.newCachedThreadPool();
  108. for (int i = 0; i < 3; i++){
  109. service.submit(producer);
  110. }
  111. for (int i = 0; i < 3; i++){
  112. service.submit(consumer);
  113. }
  114. service.shutdown();
  115. }
  116. public static void main(String[] args) throws Exception {
  117. ConditionTest.testBasket();
  118. }
  119. }
 

Java之多线程开发时多条件Condition接口的使用的更多相关文章

  1. 使用java做paypal开发时购买东西支付不成功的原因

    使用java做paypal开发时购买东西支付不成功的原因 没有设置网站习惯设定,登陆自己的paypal账户,在网站习惯设定上填写回调的url路径,这样就可以 支付成功了并且异步修改订单的状态. 支付成 ...

  2. Java网络多线程开发:java.io.EOFException

    Java网络多线程开发:java.io.EOFException 在实现韩顺平Java的多用户即使通信系统实战项目中: 对于客户端线程的停止,老韩是向服务器端发送一个消息对象,提示服务器端进行资源释放 ...

  3. Java Tread多线程(1)实现Runnable接口

    作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39347245 本文演示,Tread多线程实现Runnable接口,以及简单 ...

  4. JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)

    实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...

  5. 多线程之线程通信条件Condition

    Condition是Locks锁下的还有一种线程通信之间唤醒.堵塞的实现.它以下的await,和signal可以实现Object下的wait,notify和notifyAll的所有功能,除此之外改监视 ...

  6. 多线程之线程通信条件Condition二

    接上一篇,实现Condition三个条件,有这样一个应用: 1. 有三个进程,第一个进程运行1次,第二个进程运行2次,第三个进程运行3次: 2. 先运行第二个进程,然后第一个,然后第三个: 3.  依 ...

  7. java中多线程中测试某个条件的变化用 if 还是用 while?

    最近在研究wait和notify方法,发现有个地方要注意,但是网上又说得不是很明白的地方,就是经典的生产者和消费模式,使用wait和notify实现,判断list是否为空的这个为什么要用while而不 ...

  8. sdk开发时,对外暴露的接口封装

    思考,用同步还是异步? 实质就是屏蔽一些东西,让使用者直接传参数 拿结果 而不用关心具体实现 eg.登陆接口 1.定义接口LoginCallBack,两个函数 请求成功和失败 public inter ...

  9. JAVA之多线程的创建

    转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...

随机推荐

  1. python 03

    数据结构 在 python 中有4种内建数据结构, 列表, 元组, 字典和集合. 列表 list 有序项目的数据结构, 类似数组, 是对象. 列表用中括号中用逗号分隔的项目定义.例如 ['apple' ...

  2. 控制移动端页面的缩放(meta)

    meta标签中的content属性里有一个width=device-width的值,这个值就是用来告诉浏览器,该页面将要使用设备的宽度来解析,后面的属性值则是告诉该页面: user-scalable= ...

  3. maven工程使用spring-boot-devtools进行热部署,更改代码避免重启web容器

    spring-boot-devtools 是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去.相关Blog: 点击打开链接 原理是在发现代码有更改之后,重新启动应用 ...

  4. tensorflow版的bvlc模型

    研究相关的图片分类,偶然看到bvlc模型,但是没有tensorflow版本的,所以将caffe版本的改成了tensorflow的: 关于模型这个图: 下面贴出通用模板: from __future__ ...

  5. rpm 软件安装

    安装 vi 软件 rpm q查询 a全部软件 e 卸载 i 安装 v 显示进度 h 以#显示 首先确定软件时候安装 rpm 实现软件的安装 卸载 升级 查询等 1)查询是否已经安装过 rpm -qa ...

  6. kaggle数据挖掘竞赛初步--Titanic<原始数据分析&缺失值处理>

    Titanic是kaggle上的一道just for fun的题,没有奖金,但是数据整洁,拿来练手最好不过啦. 这道题给的数据是泰坦尼克号上的乘客的信息,预测乘客是否幸存.这是个二元分类的机器学习问题 ...

  7. webservice服务的简单应用

    本人目前刚接触到webservice服务,知道它是一个为外部提供接口的服务,下面大概讲一下webservice是如何应用的. 在此我只针对ASP.NET 讲一个是如何应用的: 1. 打开VS ,在WE ...

  8. jQuery验证插件 Validate详解

    1.引入必要的文件,以及语言中文提示包 2.使用规则如下: 序号 规则 描述 1 required:true 必须输入的字段. 2 remote:"check.php" 使用 aj ...

  9. Linux 批量修改文件名

    背景:在研究MP4解码播放的时候音视频字幕的分片命名不符合规范,分片个数太多只能脚本实现. 解决问题类型: 1.将Garfield1HD_261_dan-*.m4s 统一转换为Garfield1HD_ ...

  10. Eclipse快捷键汇总

    [ALT+/] 此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ALT+/]快捷键带来的好处吧. 2 [Ctrl+O] ...