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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

目的:生产一个,消费一个代码如下:
  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.                 if(flag){
  8.                         try{this.wait();}
  9.                         catch(Exception e){}
  10.                 }
  11.                 this.name=name+"....."+count++;
  12.                 System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);
  13.                 flag=true;
  14.                 this.notify();
  15.         }
  16.         public synchronized void out(){
  17.                 if(!flag){
  18.                         try{this.wait();}
  19.                         catch(Exception e){}
  20.                 }
  21.                 System.out.println(Thread.currentThread().getName()+"........消费........"+this.name);
  22.                 flag=false;
  23.                 this.notify();
  24.         }
  25. }
  26. class Producer implements Runnable
  27. {       
  28.         private Resource res;
  29.         Producer(Resource res){
  30.                 this.res=res;
  31.         }
  32.         public void run()
  33.         {
  34.                 while(true){
  35.                         res.set("+商品+");
  36.                 }
  37.         }
  38. }
  39. class Customer implements Runnable
  40. {
  41.         private Resource res;
  42.         Customer(Resource res){
  43.                 this.res=res;
  44.         }
  45.         public void run(){
  46.                 while(true){
  47.                         res.out();
  48.                 }
  49.         }
  50. }
  51. class  ThreadProCus
  52. {
  53.         public static void main(String[] args)
  54.         {
  55.                 Resource res=new Resource();
  56.                 Producer pro=new Producer(res);
  57.                 Customer cus=new Customer(res);
  58.                 Thread t1=new Thread(pro);
  59.                 Thread t2=new Thread(cus);
  60.                 t1.start();
  61.                 t2.start();
  62.         }
  63. }
复制代码
但是一般来说, 实际开发是有多个线程来生产消费的,
运行的话,就会有问题,
。这样就不对了, 为啥?
原因:线程可能唤醒的是本方的线程, 而将前一个给覆盖了, 这时就需要将这个线程再次判断一下, 所以需要把if变成while循环。
而这样, 可能会将这些线程都给冻结了, 因此需要将notify(),改成notifyAll().
代码如下:
  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.                 while(flag){//用if判断, 数据错误, while循环,全部等待, 不是活着的, 冻结了
  8.                         try{this.wait();}
  9.                         catch(Exception e){}
  10.                 }
  11.                 this.name=name+"....."+count++;
  12.                 System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);
  13.                 flag=true;
  14.                 this.notifyAll();
  15.         }
  16.         public synchronized void out(){
  17.                 while(!flag){
  18.                         try{this.wait();}
  19.                         catch(Exception e){}
  20.                 }
  21.                 System.out.println(Thread.currentThread().getName()+"........消费........"+this.name);
  22.                 flag=false;
  23.                 this.notifyAll();
  24.         }
  25. }
  26. class Producer implements Runnable
  27. {       
  28.         private Resource res;
  29.         Producer(Resource res){
  30.                 this.res=res;
  31.         }
  32.         public void run()
  33.         {
  34.                 while(true){
  35.                         res.set("+商品+");
  36.                 }
  37.         }
  38. }
  39. class Consumer implements Runnable
  40. {
  41.         private Resource res;
  42.         Consumer(Resource res){
  43.                 this.res=res;
  44.         }
  45.         public void run(){
  46.                 while(true){
  47.                         res.out();
  48.                 }
  49.         }
  50. }
  51. class  ThreadProCus1
  52. {
  53.         public static void main(String[] args)
  54.         {
  55.                 Resource res=new Resource();
  56.                 Producer pro=new Producer(res);
  57.                 Consumer con=new Consumer(res);
  58.                 Thread t1=new Thread(pro);
  59.                 Thread t2=new Thread(pro);
  60.                 Thread t3=new Thread(con);
  61.                 Thread t4=new Thread(con);
  62.                 t1.start();
  63.                 t2.start();
  64.                 t3.start();
  65.                 t4.start();
  66.         }
  67. }
复制代码
总结:
1,对于多个生产和消费:
为什么要定义while判断标记。
原因:让被唤醒的线程再一次判断标记。
2,为什么定义notifyAll().
因为需要将对方的线程唤醒。
因为只用notify(),容易出现只唤醒本方的线程的情况,导致程序中的所有的线程都在等待。










0 个回复

您需要登录后才可以回帖 登录 | 加入黑马