zoukankan      html  css  js  c++  java
  • 线程间通信 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)


  • 相关阅读:
    Android组件化和插件化开发
    开发一流的 Android SDK:Fabric SDK 的创建经验
    关系 和非关系 阻塞非阻塞的区别
    AJAX 中JSON 和JSONP 的区别 以及请求原理
    九马画山数命运, 一身伴君不羡仙! 与代码不离不弃!
    移动端 transitionEnd函数用来检测过渡是否完成
    2017前端该学的知识 分享墨白的文章、大家共勉!
    移动端和pc端事件绑定方式以及取消浏览器默认样式和取消冒泡
    今天要带来的是移动端开发的基础内容
    离线存储
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276471.html
Copyright © 2011-2022 走看看