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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 136616244 中级黑马   /  2014-5-7 15:40  /  1368 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 136616244 于 2014-5-8 21:37 编辑

这段代码为什么会停止循环呢?
  1. package 多线程;

  2. class 生产者消费者 {
  3.         public static void main(String[] args) {
  4.                 Res r = new Res();
  5.                 boolean flag = false;
  6.                 Producer p = new Producer(r);
  7.                 Consumer c = new Consumer(r);
  8.                 Thread t = new Thread(p);
  9.                 Thread t2 = new Thread(c);
  10.                
  11.                 t.start();
  12.                 t2.start();
  13.         }
  14. }
  15. class Res{
  16.         boolean flag = false;
  17.         int count = 0;
  18.         public synchronized void setResource(){
  19.                 count++;
  20.                 System.out.println(Thread.currentThread().getName()+"生产者------"+count);
  21.         }
  22.         public synchronized void getResource(){
  23.                 System.out.println(Thread.currentThread().getName()+"消费者。。。。。。。。。。。。"+count);
  24.         }
  25. }
  26. class Producer implements Runnable{
  27.         Res r;
  28.         
  29.         Producer(Res r ){
  30.                 this.r = r;

  31.         }
  32.         public void run(){
  33.                 while(true){
  34.                         if(!(r.flag)){
  35.                                 r.setResource();
  36.                                 r.flag =true;
  37.                         }
  38.         
  39.                 }
  40.         }
  41. }
  42. class Consumer implements Runnable{
  43.         Res r;
  44.         Consumer(Res r){
  45.                 this.r = r;

  46.         }
  47.         public void run(){
  48.                 while(true){
  49.                         if(r.flag){
  50.                                 r.getResource();
  51.                                 r.flag =false;
  52.                         }
  53.                 }

  54.         }
  55. }
复制代码

9 个回复

倒序浏览
  1. 这样就没问题了。

  2. public class test {

  3.         public static void main(String[] args) {

  4.                Res r = new Res();
  5.   
  6.                Producer p = new Producer(r);

  7.                Consumer c = new Consumer(r);

  8.                Thread t = new Thread(p);
  9.                
  10.                Thread t2 = new Thread(c);
  11.                
  12.                t2.start();
  13.       
  14.                 t.start();



  15.        }

  16. }

  17. class Res
  18. {

  19.        private boolean flag = false;

  20.        private int count = 0;

  21.         public  void setResource()
  22.         {

  23.                 while(true)
  24.                 {
  25.                         synchronized(Res.class)
  26.                         {
  27.                                 if(!flag)
  28.                                 {
  29.                                 count++;
  30.                               System.out.println(Thread.currentThread().getName()+"生产者------"+count);
  31.                               flag = true;
  32.                             }
  33.                         }
  34.                 }
  35.         }

  36.        public  void getResource()
  37.        {

  38.                while(true)
  39.                {
  40.                        synchronized(Res.class)
  41.                                {
  42.                                     if(flag)
  43.                                           {
  44.                                                   System.out.println(Thread.currentThread().getName()+"消费者。"+"。。。。。。。。。。。"+count);
  45.                                                   flag = false;
  46.                                           }
  47.                                }

  48.                }   

  49.        }

  50. }

  51. class Producer implements Runnable
  52. {

  53.        Res r;

  54.        Producer(Res r )
  55.        {
  56.               this.r = r;

  57.        }

  58.        public void run()
  59.        {
  60.                r.setResource();
  61.         }

  62. }

  63. class Consumer implements Runnable
  64. {

  65.        Res r;

  66.        Consumer(Res r)
  67.        {

  68.                 this.r = r;
  69.                
  70.        }

  71.        public void run()
  72.        {
  73.                r.getResource();
  74.               
  75.         }

  76. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 136616244 于 2014-5-7 17:14 编辑


我想问的是   生产者消费者拿到cpu的执行权不是随机的吗,为什么需要唤醒等待呢?
我的问题出在哪了

回复 使用道具 举报
136616244 发表于 2014-5-7 17:13
我想问的是   生产者消费者拿到cpu的执行权不是随机的吗,为什么需要唤醒等待呢?
我的问题出在哪了

唤醒等待主要是用来进行线程间通信,就像生产者-消费者问题一样,生产者生产一个物品,就唤醒消费者去拿刚生产的物品,当他发现消费者还没有取走上一次生产的物品时,就进入睡眠状态,等消费者取走物品后,消费者便将生产者唤醒,生产者继续生产物品,同样,消费者如果发现没有物品可拿,便进入等待状态,等生产者生产出一个物品之后,就将消费者唤醒,消费者就去取物品。这就完成线程间的通信。
回复 使用道具 举报
  1. public class test {

  2.         public static void main(String[] args) {

  3.                Res r = new Res();
  4.   
  5.                Producer p = new Producer(r);

  6.                Consumer c = new Consumer(r);

  7.                Thread t = new Thread(p);
  8.                
  9.                Thread t2 = new Thread(c);
  10.                
  11.                t.start();
  12.       
  13.                 t2.start();



  14.        }

  15. }

  16. class Res
  17. {

  18.        public boolean flag = false;

  19.        private int count = 0;

  20.         public  synchronized void setResource()
  21.         {

  22.                                 count++;
  23.                               System.out.println(Thread.currentThread().getName()+"生产者------"+count);
  24.                 }
  25.      

  26.        public synchronized void getResource()
  27.        {


  28.                                                   System.out.println(Thread.currentThread().getName()+"消费者。"+"。。。。。。。。。。。"+count);

  29.                }   


  30.        }



  31. class Producer implements Runnable
  32. {

  33.        Res r;

  34.        Producer(Res r )
  35.        {
  36.               this.r = r;

  37.        }

  38.        public void run()
  39.        {
  40.                while(true)
  41.                {
  42.                        if(!r.flag)
  43.                        {
  44.                                r.setResource();
  45.                                r.flag = true;
  46.                        }
  47.                        try
  48.                        {

  49.                                Thread.sleep(100);
  50.                         } catch (Exception e) {
  51.                         }
  52.                }
  53.         }

  54. }

  55. class Consumer implements Runnable
  56. {

  57.        Res r;

  58.        Consumer(Res r)
  59.        {

  60.                 this.r = r;
  61.                
  62.        }

  63.        public void run()
  64.        {
  65.                while(true)
  66.                {
  67.                        if(r.flag)
  68.                        {
  69.                                r.getResource();
  70.                                r.flag =false;
  71.                        }
  72.                        try {
  73.                                Thread.sleep(100);
  74.                         } catch (Exception e) {
  75.                                 e.printStackTrace();
  76.                         }
  77.                }
  78.               
  79.         }

  80. }

  81. 如果硬是要用lz的代码,就要在生产者执行完setSouce释放所后,自己有充分的时间去设置flag而不用得到下次自己得到cpu时间后再来设置flag值,消费者也如此,如果不这样,程序运行太快,同步范围又太窄,就容易出现相互等待的问题。
复制代码
回复 使用道具 举报

没明白,qq多少啊?
回复 使用道具 举报

我想问一下,楼主代码出现什么错误了,代码在我电脑上没出现异常,或停止啊:)
回复 使用道具 举报
136616244 发表于 2014-5-7 18:09
没明白,qq多少啊?

我想问一下,楼主代码出现什么错误了,代码在我电脑上没出现异常,或停止啊:)
回复 使用道具 举报
sheng6699 发表于 2014-5-7 20:06
我想问一下,楼主代码出现什么错误了,代码在我电脑上没出现异常,或停止啊 ...

你QQ多少  我运行给你看看
回复 使用道具 举报
136616244 发表于 2014-5-7 20:12
你QQ多少  我运行给你看看

2564673498 。我想看下,正在学习中。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马