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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© run_wind 中级黑马   /  2014-11-3 01:02  /  1787 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 run_wind 于 2014-11-3 01:11 编辑




  1. class ProducerConsumerDemo
  2. {
  3. public static void main(String[] args)
  4. {
  5. Resource r = new Resource();

  6. Producer pro = new Producer(r);
  7. Consumer con = new Consumer(r);

  8. Thread t1 = new Thread(pro);
  9. Thread t2 = new Thread(pro);
  10. Thread t3 = new Thread(con);
  11. Thread t4 = new Thread(con);

  12. t1.start();
  13. t2.start();
  14. t3.start();
  15. t4.start();

  16. }
  17. }

  18. /*
  19. 对于多个生产者和消费者。
  20. 为什么要定义while判断标记。
  21. 原因:让被唤醒的线程再一次判断标记。


  22. 为什么定义notifyAll,
  23. 因为需要唤醒对方线程。
  24. 因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。

  25. */
  26. class Resource
  27. {
  28. private String name;
  29. private int count = 1;
  30. private boolean flag = false;
  31. public synchronized void set(String name)
  32. {
  33. while(flag)
  34. try{this.wait();}catch(Exception e){}//t1(放弃资格) t2(获取资格)
  35. this.name = name+"--"+count++;

  36. System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
  37. flag = true;
  38. this.notifyAll();
  39. }
  40. public synchronized void out()
  41. {
  42. while(!flag)
  43. try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)
  44. System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
  45. flag = false;
  46. this.notifyAll();
  47. }
  48. }

  49. class Producer implements Runnable
  50. {
  51. private Resource res;

  52. Producer(Resource res)
  53. {
  54. this.res = res;
  55. }
  56. public void run()
  57. {
  58. while(true)
  59. {
  60. res.set("+商品+");
  61. }
  62. }
  63. }

  64. class Consumer implements Runnable
  65. {
  66. private Resource res;

  67. Consumer(Resource res)
  68. {
  69. this.res = res;
  70. }
  71. public void run()
  72. {
  73. while(true)
  74. {
  75. res.out();
  76. }
  77. }
  78. }
复制代码

如题,while判断为什么会每次都有判断的?不是在try才停住了么,应该是不判断了直接往下执行了才对,难道是wait?java 线程wait()与notify()的用法(被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行)

评分

参与人数 1黑马币 +1 收起 理由
杨佳名 + 1

查看全部评分

9 个回复

倒序浏览
本帖最后由 青鱼 于 2014-11-3 02:16 编辑

楼主大概是没有理解到 try..cathc 的用法吧

try 是用于检测 try{ .. } 中的错误的.  没有抛错就不会被 try 检测到, 既然 try 检测通过, 当然会顺利运行 {... } 里面的语句.
如果 try{...} 里面的语句有问题, 抛出错误了, 就会被 catch(Exception e) 捕抓到, 其中 Exception 是欲捕抓的错误类型, e 则包含了全部错误信息;

cathc(..){ 该语句块 } 就是当出现错误的时候执行的部分...

while 判断的是 标志位flag , 跟 try 等无关,  后面不是设置了交替修改 flag 为 false 或 true 吗..目的当然就是为了让线程相互唤醒咯...
唤醒了就立即执行代码, 没被唤醒的才是在 wait 等待中...

不知解释够清楚不..




回复 使用道具 举报
你试试这种情况:t1生产后wait(放弃资格),t2放弃资格,t3正常消费,如果是notify会唤醒第一个wait的线程(这是就是先wait的t1),此时有两个线程存活(t1和t4),若是t4抢到了执行权,t4也会wait,这时只有t1一个存活了,t1正常消费后,唤醒的将是t2,t1进入等待,t2也会进入等待,结果全部等待了。以上是只用while不用notifyAll的情形
回复 使用道具 举报
本帖最后由 郑飞 于 2014-11-3 11:00 编辑

while(flag)
{
       wait()//停在这里了,第二次回来继续往下执行就回到上面判断flag
}如果是
if(flag)
{
      wait()//停在这里,第二次回来直接出if往下执行
}
回复 使用道具 举报
郑飞 发表于 2014-11-3 10:59
while(flag)
{
       wait()//停在这里了,第二次回来继续往下执行就回到上面判断flag

如果while和wait()之间还有别的语句呢?还继续执行一次?还是只是判断一遍?
回复 使用道具 举报
青鱼 发表于 2014-11-3 02:14
楼主大概是没有理解到 try..cathc 的用法吧

try 是用于检测 try{ .. } 中的错误的.  没有抛错就不会被 try ...

异常这块确实无比头疼,被我知道用法之后先暂时跳过了。。我想知道如果wait()和while之间再有别的语句呢,是判断一遍从wait()之后继续往下,还是从while往下重新?
回复 使用道具 举报
青鱼 发表于 2014-11-3 02:14
楼主大概是没有理解到 try..cathc 的用法吧

try 是用于检测 try{ .. } 中的错误的.  没有抛错就不会被 try ...

其实说实话,用wait()为什么会try我都没搞清楚
回复 使用道具 举报
郑飞 高级黑马 2014-11-3 18:56:41
8#
run_wind 发表于 2014-11-3 17:48
如果while和wait()之间还有别的语句呢?还继续执行一次?还是只是判断一遍? ...

后面的也会执行的 执行完本次while内部代码 回到while上判断条件
回复 使用道具 举报
线程的切换的问题,  利用while 循环,就是反复判断的问题,如果不用while循环,线程在切换到if 中,就不需要再进行判断,继续往下走,就会出现,生产者连续生产了。以及消费者连续消费了两次了,出现了线程的安全问题
回复 使用道具 举报
run_wind 发表于 2014-11-3 17:54
其实说实话,用wait()为什么会try我都没搞清楚

try 是预防万一. 其实不 try 也可以, 就是程序不安全不健壮的问题.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马