• 线程间通信 wait()/notify() 用例


    考虑一个生产者/消费者模型。

     

    商品类Goods 

    class Goods { 

             private  String name; 

           public  Goods(String name)  { this.name =name; } 

          public   String  toString()  {  return "Goods[" + name + ']';  }

    }

     

    商品容器类GoodsStatck 

    class GoodsStatck{ 


       private  Goods[]buffer;

       int point =-1;

       int size; 


       GoodsStatck (int size) {  this.size = size;  buffer = new Goods[size];   } 


       public synchronized int getPoint() { return this.point; }

     

       public synchronized Goods pop() {

           if (point0) {

               return null;

           }

           Goods goods = buffer[point];

           buffer[point] = null;

           point--;

           return goods;

       }

     

       public synchronized boolean push(Goods goods){

           if (point= size - 1) {

               return false;

           }

           point++;

           buffer[point] = goods;

              return true;

       }

    }

     

    生产者类Producer 

    class Producer implements Runnable{ 


       private GoodsStatck  goodsStatck;

        private   String name; 


        Producer(String name, GoodsStatck  goodsStatck) {

           this.name = name;

           this.goodsStatck = goodsStatck;

       }

      

       public void run(){

           while (true) {

               synchronized (this.goodsStatck) {

                   Goods goods = new Goods("No-" + (this.goodsStatck.getPoint() +1));

                   boolean result =this.goodsStatck.push(goods);

                   if (result) {

                        System.out.println(name + " produce : " + goods);

                   }

                   else{

                        System.err.println("Error! The stack is full");

                   }

               }

           }

       }

    }

     

     

    消费者类Producer 

    class Consumer implements Runnable{ 


       private GoodsStatck goodsStatck;

       private String name; 


       Consumer(String name, GoodsStatck goodsStatck) {

           this.name =name;

           this.goodsStatck =goodsStatck;

       }


       public void run(){

           while (true) {

               Goods goods =this.goodsStatck.pop();

               if (goods !=null) {

                   System.out.println(name + " get : " + goods);

               }else {

                   System.err.println("Error! There is no goods in stack ");

               }

           } 

       }

    }

     

    测试程序  

           GoodsStatck goodsStatck = new GoodsStatck(2);

           Producer producer1 = new Producer("producer-1",goodsStatck);

           Producer producer2 = new Producer("producer-2",goodsStatck);

           Consumer consumer1 = new Consumer("consumer-1",goodsStatck);

           Consumer consumer2 = new Consumer("consumer-2",goodsStatck); 

           new Thread(producer1).start();

           new Thread(producer2).start();

           new Thread(consumer1).start();

           new Thread(consumer2).start(); 

     

    可能出现以下输出:

    Error!The stack is full  

    Error!There is no goods in stack

     

    即在push的时候会遇到容器GoodsStatck已满,pop的时候遇到容器GoodsStatck为空的情况。

     

    要改变这种情况,必须使用wait()/notify(),即将GoodsStatck的pop()、push() 修改如下:

     

       public synchronized Goods pop() {

           this.notifyAll();

           while (point0) {

               try {

                   this.wait();

               }catch (InterruptedException ex) { throw new RuntimeException(ex); }

           }

           Goods goods = buffer[point];

           buffer[point] = null;

           point--;

           return goods;

       }

     

       public synchronized boolean push(Goods goods){

           this.notifyAll();

           while (point= size - 1) {

               try {

                   this.wait();

               }catch (InterruptedException ex) { throw new RuntimeException(ex); }

           }

           point++;

           buffer[point] = goods;

           return true;

       }

     

    这样在遇到容器GoodsStatck为空或满的情况时(while循环中),线程将放弃锁(GoodsStatck.this)阻塞,直到满足条件。使用时候注意:

     

    1. 先唤醒其他线程,再放弃自己的锁,即先notify()/notifyAll(),再wait()

    2. wait() 方法必须放在while循环中,不能放在if条件中

    3. 一般情况下,notifyAll() 优于notify()


    可以用 java.util.concurrent包中阻塞队列 BlockingQueue(interface) 实现 ( LinkedBlockingDeque(class), ArrayBlockingQueue  (class) ,  PriorityBlockingQueue  (class)


  • 相关阅读:
    jQuery初级篇
    DOM初级篇
    CSS基础篇
    javascript 初级篇
    HTML 基础篇
    Oracle文章中常用数据表的描述
    Oracle视图基础
    Oracle序列简单应用
    Oracle关联查询关于left/right join的那点事
    赋值和算术运算符
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276471.html
Copyright © 2020-2023  润新知