7.生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)

  1 /*
  2  * 生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)
  3  * */
  4 public class TestProductorAndConsumerForLock {
  5     public static void main(String[] args) {
  6         WareHouse wareHouse = new WareHouse();
  7         Productor pd1 = new Productor(wareHouse);
  8         Consumer cs1 = new Consumer(wareHouse);
  9 
 10         new Thread(pd1, "消费者1").start();
 11         new Thread(cs1, "生产者1").start();
 12         // 若有多个 生产者消费者,可能会产生虚假唤醒(缺货了,多个生产线程等待,唤醒时,这些生产线程同时醒来,对数据进行操作,这种问题叫做虚假唤醒)
 13         // 解决办法:wait方法 尽量 使用在循环中,被唤醒之后,再去判断是否符合条件(库存是否达到上限),不符合条件
 14         // 继续等待(等待消费者去消费商品),直到 条件符合(库存有空闲)
 15         new Thread(pd1, "消费者2").start();
 16         new Thread(cs1, "生产者2").start();
 17     }
 18 }
 19 
 20 // 仓库
 21 class WareHouse {
 22     // 商品数量
 23     private int products = 0;
 24     private ReentrantLock lock = new ReentrantLock();
 25     //使用 Condition 的前提是 使用 Lock 同步锁,Condition 实例 实质上被绑定到一个锁上
 26     private Condition condition = lock.newCondition();
 27 
 28     public void set() {
 29         lock.lock();
 30         try {
 31             while (products >= 1) {
 32                 System.out.println("商品库存满了");
 33                 try {
 34                     // 如果商品满了,阻塞线程,等待消费者线程消费完成后唤醒,
 35                     condition.await();  //相当于(Object.awatit() 但是功能更强大)
 36                 } catch (InterruptedException e) {
 37                     // TODO Auto-generated catch block
 38                     e.printStackTrace();
 39                 }
 40             }
 41             System.out.println("生产了商品,剩余库存" + ++products);
 42             condition.signalAll();     //相当于 (Object.notifyAll,功能更强大)
 43         } finally {
 44             lock.unlock();
 45         }
 46 
 47     }
 48 
 49     public void get() {
 50         lock.lock();
 51         try {
 52             while (products <= 0) {
 53                 System.out.println("商品库存没了");
 54                 try {
 55                     // 如果商品没了,阻塞线程,等待生产者线程生产完成后唤醒,
 56                     condition.await();  
 57                 } catch (InterruptedException e) {
 58                     // TODO Auto-generated catch block
 59                     e.printStackTrace();
 60                 }
 61             }
 62             System.out.println("消费了商品,剩余库存" + --products);
 63             condition.signalAll();
 64         } finally {
 65             lock.unlock();
 66         }
 67 
 68     }
 69 }
 70 
 71 // 生产者
 72 class Productor implements Runnable {
 73     private WareHouse wareHouse;
 74 
 75     public Productor(WareHouse wareHouse) {
 76         this.wareHouse = wareHouse;
 77     }
 78 
 79     @Override
 80     public void run() {
 81         for (int i = 0; i < 20; i++) {
 82             try {
 83                 Thread.sleep(200); 
 84             } catch (InterruptedException e) {
 85                 // TODO Auto-generated catch block
 86                 e.printStackTrace();
 87             }
 88             wareHouse.get();
 89         }
 90     }
 91 
 92 }
 93 
 94 // 消费者
 95 class Consumer implements Runnable {
 96     private WareHouse wareHouse;
 97 
 98     public Consumer(WareHouse wareHouse) {
 99         this.wareHouse = wareHouse;
100     }
101 
102     @Override
103     public void run() {
104         for (int i = 0; i < 20; i++) {
105 
106             wareHouse.set();
107         }
108     }
109 
110 }
原文地址:https://www.cnblogs.com/xuzekun/p/7429123.html