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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 唐巍 黑马帝   /  2012-3-20 03:16  /  1451 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

问题代码:
class Resource
{
        private String name;
        private int count=1;
        private boolean flag=false;
        public synchronized void set(String name)
        {
                while(flag)
                        try{this.wait();}catch(Exception e){}
                this.name=name+"--"+count++;
                System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
                flag=true;
                this.notify();
        }
        public synchronized void out()
        {
                while(!flag)
                        try{this.wait();}catch(Exception e){}
                System.out.println(Thread.currentThread().getName()+"...消费者......."+this.name);
                flag=false;
                this.notify();
        }
}
class Producer implements Runnable
{
        private Resource res;
        Producer(Resource res)
        {
                this.res=res;
        }
        public void run()
        {
                while (true)
                {
                        res.set("+商品+");
                }
        }
}
class Consumer implements Runnable
{
        private Resource res;
        Consumer(Resource res)
        {
                this.res=res;
        }
        public void run()
        {
                while(true)
                {
                        res.out();
                }
        }
}
class ProducerConsumerDemo
{
        public static void main(String[] args)
        {
                Resource r=new Resource();
                Producer pro=new Producer(r);
                Consumer con=new Consumer(r);
                Thread t1=new Thread(pro);
                Thread t2=new Thread(pro);
                Thread t3=new Thread(con);
                Thread t4=new Thread(con);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}

程序总是运行一会儿就卡住不动了,也没有报异常,这是怎么回事?

2 个回复

倒序浏览
将Resource类中两句:
this.notify();
改成:
this.notifyAll();
我记得毕老师的视频有提到这个问题的。
回复 使用道具 举报
本帖最后由 代臣 于 2012-3-20 08:23 编辑
  1. class Resource
  2. {
  3.         private String name;
  4.         private int count=1;
  5.         private boolean flag=false;
  6.         public synchronized void set(String name)
  7.         {
  8.                 while(flag)
  9.                         try{this.wait();}catch(Exception e){}
  10.                 this.name=name+"--"+count++;
  11.                 System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
  12.                 flag=true;
  13.                 this.notifyAll();//改为了notifyAll
  14.         }
  15.         public synchronized void out()
  16.         {
  17.                 while(!flag)
  18.                         try{this.wait();}catch(Exception e){}
  19.                 System.out.println(Thread.currentThread().getName()+"...消费者......."+this.name);
  20.                 flag=false;
  21.                 this.notifyAll();//改为了notifyAll
  22.         }
  23. }
  24. class Producer implements Runnable
  25. {
  26.         private Resource res;
  27.         Producer(Resource res)
  28.         {
  29.                 this.res=res;
  30.         }
  31.         public void run()
  32.         {
  33.                 while (true)
  34.                 {
  35.                         res.set("+商品+");
  36.                 }
  37.         }
  38. }
  39. class Consumer implements Runnable
  40. {
  41.         private Resource res;
  42.         Consumer(Resource res)
  43.         {
  44.                 this.res=res;
  45.         }
  46.         public void run()
  47.         {
  48.                 while(true)
  49.                 {
  50.                         res.out();
  51.                 }
  52.         }
  53. }
  54. class ProducerConsumerDemo
  55. {
  56.         public static void main(String[] args)
  57.         {
  58.                 Resource r = new Resource();
  59.                 Producer pro = new Producer(r);
  60.                 Consumer con = new Consumer(r);
  61.                 Thread t1 = new Thread(pro);
  62.                 Thread t2 = new Thread(pro);
  63.                 Thread t3 = new Thread(con);
  64.                 Thread t4 = new Thread(con);
  65.                 t1.start();
  66.                 t2.start();
  67.                 t3.start();
  68.                 t4.start();
  69.         }
  70. }

  71. //程序总是运行一会儿就卡住不动了,也没有报异常,这是怎么回事?
  72. /*
  73. 问题的症结是多个生产者和消费者线程存在的话,容易出现所有线程等待的情况,
  74. 解决的办法是利用notifyAll()方法唤醒所有的线程,其中就包括对方线程,因为线
  75. 程运行过程中可能会出现对方线程一直处于等待状态,比如消费者要消费的时候,
  76. 生产者并没有生产set()这个动作,因为该动作处于等待状态,没有Resource消费
  77. 者线程就无法进行下去,也就不能out(),从而产生所有线程等待的状况。
  78. */
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马