A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 郭冰川 于 2013-1-13 14:01 编辑

现在是只有t2有执行资格其他三个都是wait状态, 毕老师说if只能判断一次,要改成while,但是t2已经进入while循环体里面了,为什么唤醒后还要回去判断一次呢?

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

5 个回复

正序浏览
罗会涛 发表于 2013-1-13 11:23
不知道在while后面加个括号把循环体括起来,你理解会不会容易些。
while被唤醒,但是唤醒时它任然在循环体 ...

ok , 懂了
回复 使用道具 举报
  1. import java.util.concurrent.locks.*;
  2. class ProducterConsumerDemo2
  3. {
  4. public static void main(String[] args)
  5. {
  6. Resource r = new Resource(); //定义商品资源
  7. Producter pro = new Producter(r);//创建生产者对象
  8. Consumer son = new Consumer(r); //创建消费者对象

  9. //创建两个生产者即两个线程
  10. Thread t1 = new Thread(pro);
  11. Thread t2 = new Thread(pro);

  12. //创建两个消费者即两个线程
  13. Thread t3 = new Thread(son);
  14. Thread t4 = new Thread(son);

  15. //启动四个线程并执行相应的run方法
  16. t1.start();
  17. t2.start();
  18. t3.start();
  19. t4.start();

  20. }
  21. }

  22. class Resource
  23. {
  24. private String name; //商品的名字
  25. private int count =1; //商品的编号
  26. private boolean flag = false;

  27. private Lock lock = new ReentrantLock();

  28. private Condition condition_pro = lock.newCondition();
  29. private Condition condition_con = lock.newCondition();

  30. public void set(String name)throws InterruptedException
  31. {
  32. lock.lock();
  33. try
  34. {
  35. while(flag)
  36. condition_pro.await();
  37. this.name = name + "--" + count++;//

  38. System.out.println(Thread.currentThread().getName() + "...生产者 " + this.name);
  39. flag = true;
  40. condition_con.signal();
  41. }
  42. finally{
  43. lock.unlock();//释放锁的操作一定要执行
  44. }
  45. }
  46. public void out()throws InterruptedException
  47. {
  48. lock.lock();
  49. try
  50. {
  51. while(!flag)
  52. condition_con.await();
  53. System.out.println(Thread.currentThread().getName() + "...消费者————" + this.name);
  54. flag = false;
  55. condition_pro.signal();
  56. }finally{
  57. lock.unlock();
  58. }
  59. }
  60. }
  61. // 商品的生产者
  62. class Producter implements Runnable
  63. {
  64. private Resource res;

  65. Producter(Resource res)
  66. {
  67. this.res = res;
  68. }
  69. public void run()
  70. {
  71. while(true)
  72. {
  73. try
  74. {
  75. res.set("商品+");
  76. }
  77. catch (InterruptedException e)
  78. {
  79. }

  80. }
  81. }
  82. }
  83. //商品的消费者
  84. class Consumer implements Runnable
  85. {
  86. private Resource res;

  87. Consumer(Resource res)
  88. {
  89. this.res = res;
  90. }
  91. public void run()
  92. {
  93. while(true)
  94. {
  95. try
  96. {
  97. res.out();
  98. }
  99. catch (InterruptedException e)
  100. {

  101. }
  102. }
  103. }
  104. }
复制代码
这样是正确的写法!你看看吧!
回复 使用道具 举报
不知道在while后面加个括号把循环体括起来,你理解会不会容易些。
while被唤醒,但是唤醒时它任然在循环体中,如果条件(即flag)不改变,这个循环是个死循环,相当于while(true){},大括号中的代码会不断执行,当然线程会再次wait。如果是if没有这个问题,它只判断一次。
回复 使用道具 举报
t2已经进入while循环体里面了,但是苏醒后还要判断
是的
因为 t2 抢到线程时,可能没有执行权,还在线程池里缓冲,这时把这个线程等待了,当然是还没有判断。
你再次唤醒时,肯定是先判断,再走程序嘛。
回复 使用道具 举报
while会跳出当前循环,重新循环,而if只会接着往下走,确保同步
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马