来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291471.html

  1. import java.util.concurrent.ExecutorService;
  2.  
  3. import java.util.concurrent.Executors;
  4.  
  5. import java.util.concurrent.locks.Condition;
  6.  
  7. import java.util.concurrent.locks.Lock;
  8.  
  9. import java.util.concurrent.locks.ReentrantLock;
  10.  
  11. /**
  12.  
  13. *有时候线程取得lock后需要在一定条件下才能做某些工作,比如经典的Producer和Consumer问题
  14.  
  15. *在Java 5.0以前,这种功能是由Object类的wait(),notify()和notifyAll()等方法实现的
  16.  
  17. *在5.0里面,这些功能集中到了Condition这个接口实现
  18.  
  19. */
  20.  
  21. /**
  22.  
  23. * 使用Condition的关键技术点如下:
  24.  
  25. * 1.通过Lock的newCondition方法创建Condition的对象
  26.  
  27. * 2.Condition的await方法使当前线程进入等待状态,并且释放它占据的Lock,直到有其他的线程唤醒当前线程时,重新占有Lock.
  28.  
  29. * 3.Condition的signal方法唤醒其他正在等待该Condition的线程.
  30.  
  31. */
  32.  
  33. public class ConditionTest {
  34.  
  35. /**
  36.  
  37. * 篮子程序,这里为了简化问题,篮子中最多只能有一个苹果
  38.  
  39. * Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定
  40.  
  41. * 等到Producer往篮子里放了苹果后再去拿来吃。
  42.  
  43. * 否则它也需要暂时解锁等Comsumer把苹果吃了才能往篮子里放苹果。
  44.  
  45. */
  46.  
  47. public static class Basket{
  48.  
  49. //锁
  50.  
  51. Lock lock = new ReentrantLock();
  52.  
  53. //根据锁产生Condition对象
  54.  
  55. Condition produced = lock.newCondition();
  56.  
  57. Condition consumed = lock.newCondition();
  58.  
  59. //篮子里的苹果数,最多为1
  60.  
  61. int num = 0;
  62.  
  63. //生产苹果,往篮子里放
  64.  
  65. public void produce() throws InterruptedException{
  66.  
  67. //获得锁
  68.  
  69. lock.lock();
  70.  
  71. System.out.println("Producer get a lock...");
  72.  
  73. try{
  74.  
  75. //判断是否满足生产条件
  76.  
  77. while(num == 1){
  78.  
  79. //如果有苹果,则不生产,放弃锁,进入睡眠
  80.  
  81. //等待消费者消费
  82.  
  83. System.out.println("Producer sleep...");
  84.  
  85. consumed.await();
  86.  
  87. System.out.println("Producer awaked...");
  88.  
  89. }
  90.  
  91. //生产苹果
  92.  
  93. Thread.sleep(500);
  94.  
  95. System.out.println("Producer produced an Apple.");
  96.  
  97. num = 1;
  98.  
  99. //通知等待produced Condition的线程
  100.  
  101. produced.signal();
  102.  
  103. }finally{
  104.  
  105. lock.unlock();
  106.  
  107. }
  108.  
  109. }
  110.  
  111. //消费苹果,从篮子里取
  112.  
  113. public void consume() throws InterruptedException{
  114.  
  115. //获得锁
  116.  
  117. lock.lock();
  118.  
  119. System.out.println("Consumer get a lock...");
  120.  
  121. try{
  122.  
  123. //判断是否满足消费条件
  124.  
  125. while(num == 0){
  126.  
  127. //如果没有苹果,无法消费,则放弃锁,进入睡眠
  128.  
  129. //等待生产者生产苹果
  130.  
  131. System.out.println("Consumer sleep...");
  132.  
  133. produced.await();
  134.  
  135. System.out.println("Consumer awaked...");
  136.  
  137. }
  138.  
  139. //吃苹果
  140.  
  141. Thread.sleep(500);
  142.  
  143. System.out.println("Consumer consumed an Apple.");
  144.  
  145. num = 0;
  146.  
  147. //发信号唤醒某个等待consumed Condition的线程
  148.  
  149. consumed.signal();
  150.  
  151. } finally {
  152.  
  153. lock.unlock();
  154.  
  155. }
  156.  
  157. }
  158.  
  159. }
  160.  
  161. //测试Basket程序
  162.  
  163. public static void testBasket() throws Exception{
  164.  
  165. final Basket basket = new Basket();
  166.  
  167. //定义一个producer
  168.  
  169. Runnable producer = new Runnable(){
  170.  
  171. public void run() {
  172.  
  173. try{
  174.  
  175. basket.produce();
  176.  
  177. }catch(InterruptedException ex){
  178.  
  179. ex.printStackTrace();
  180.  
  181. }
  182.  
  183. }
  184.  
  185. };
  186.  
  187. //定义一个consumer
  188.  
  189. Runnable consumer = new Runnable(){
  190.  
  191. public void run(){
  192.  
  193. try{
  194.  
  195. basket.consume();
  196.  
  197. }catch(InterruptedException ex){
  198.  
  199. ex.printStackTrace();
  200.  
  201. }
  202.  
  203. }
  204.  
  205. };
  206.  
  207. //各生产3个consumer和producer
  208.  
  209. ExecutorService service = Executors.newCachedThreadPool();
  210.  
  211. for(int i = 0; i <3; i++){
  212.  
  213. service.submit(producer);
  214.  
  215. }
  216.  
  217. for(int i = 0;i<3;i++){
  218.  
  219. service.submit(consumer);
  220.  
  221. }
  222.  
  223. service.shutdown();
  224.  
  225. }
  226.  
  227. public static void main(String... args)throws Exception{
  228.  
  229. ConditionTest.testBasket();
  230.  
  231. }
  232.  
  233. }

JDK5.0 特性-线程 Condition的更多相关文章

  1. JDK5.0特性-线程 Callable和Future

    来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291466.html import java.util.concurrent.Callable ...

  2. JDK5.0 特性线程 同步装置之CountDownLatch 同步装置之CyclicBarrier 线程 BlockingQueue

    来自:http://www.cnblogs.com/taven/category/475298.html import java.util.concurrent.CountDownLatch; imp ...

  3. JDK5.0 特性-线程锁Lock

    来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291470.html import java.util.concurrent.Executor ...

  4. JDK5.0 特性-线程同步装置之Semaphore

    来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291474.html import java.util.ArrayList; import j ...

  5. JDK5.0 特性-线程任务执行架构 ScheduledExecutorService

    来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291469.html import java.util.concurrent.Callable ...

  6. JDK5.0 特性 监控与管理虚拟机

    来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291465.html import java.lang.management.ClassLoa ...

  7. JDK5.0特性,使用ProcessBuilder执行本地命令

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.IO ...

  8. 集合框架-工具类-JDK5.0特性-函数可变参数

    1 package cn.itcast.p4.news.demo; 2 3 public class ParamterDemo { 4 5 public static void main(String ...

  9. 集合框架-工具类-JDK5.0特性-ForEach循环

    1 package cn.itcast.p4.news.demo; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 impo ...

随机推荐

  1. nginx网站攻击防护

    1.上上个月架构全部迁移上云以后,总的来说比较稳定,业务量也上来,可爱的坏人也来了,7X24小时不停恶意攻击我的网站,第一次收到报警是网站流入流量1分钟以内连续3次超过1000000bps,换算下1M ...

  2. 虚拟化(三):vsphere套件的安装注意及使用

     虚拟化(一):虚拟化及vmware产品介绍 虚拟化(二):虚拟化及vmware workstation产品使用 虚拟化(五):vsphere高可用群集与容错 vsphere套件里面基本的组件有e ...

  3. 罪恶黑名单第四季/全集The Blacklist迅雷下载

    英文全名The Blacklist,第1季(2016)NBC.本季看点:<罪恶黑名单>我们知道:剧情紧接第三季结尾,每个人——Liz,Red以及特别行动组的其他人——似乎都有许多故事可说: ...

  4. 调用人人网API

    大致步骤与上篇调用新浪微博API类似.只是感觉新浪微博的做的更好一些,人人网的非常多要手动操作 与新浪微博类似,先在人人网开放平台http://dev.renren.com/注冊站内应用, 把该填的填 ...

  5. information_schema系列十

    information_schema系列十   1:INNODB_FT_CONFIG 这张表存的是全文索引的信息,查询前可以先通过以下语句查询一下开启全文索引的表: show variables li ...

  6. python的重试库tenacity用法以及类似库retry、requests实现

    介绍 tenacity is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simpli ...

  7. jQuery.data() 的实现方式,jQuery16018518865841457738的由来,jQuery后边一串数字的由来

    原文地址: http://xxing22657-yahoo-com-cn.iteye.com/blog/1042440 jQuery.data() 的实现方式 jQuery.data() 的作用是为普 ...

  8. RV32A指令集

    RV32A指令包括两类:AMO(atomic memory operation)指令,Load-Reserved/Store-Conditional指令 Category Fmt RV32I base ...

  9. xenapp 6.5 客户端插件第一次安装总是跳到官网

    部署完xenapp6.5后,在没有安装插件的客户端登录时,会出现“下载客户端插件”界面 其实网上已经有很多解决方案,大同小已,只是不知道为什么不适合我安装的版本而已.我安装时最新的版本xenapp 6 ...

  10. [leetcode]Word Ladder II @ Python

    [leetcode]Word Ladder II @ Python 原题地址:http://oj.leetcode.com/problems/word-ladder-ii/ 参考文献:http://b ...