条件阻塞Condition的应用

复制代码
  1 import java.util.Random;
  2 import java.util.concurrent.ExecutorService;
  3 import java.util.concurrent.Executors;
  4 import java.util.concurrent.locks.Condition;
  5 import java.util.concurrent.locks.Lock;
  6 import java.util.concurrent.locks.ReentrantLock;
  7  
  8 /**
  9  * 有时候线程取得lock后需要在一定条件下才能做某些工作,比如说经典的Producer和Consumer问题。 在Java
 10  * 5.0以前,这种功能是由Object类的wait(), notify()和notifyAll()等方法实现的,
 11  * 在5.0里面,这些功能集中到了Condition这个接口来实现。
 12  */
 13 public class ConditionTest {
 14  
 15         /**
 16         * 篮子程序。Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定,
 17         * 等到Producer往篮子里放了苹果后再去拿来吃。而Producer必须等到篮子空了才能往里放苹果,
 18         * 否则它也需要暂时解锁等Consumer把苹果吃了才能往篮子里放苹果。
 19         */
 20         public static class Basket {
 21                // 锁
 22               Lock lock = new ReentrantLock();
 23                // 根据锁产生Condition对象
 24               Condition produced = lock .newCondition();
 25               Condition consumed = lock .newCondition();
 26                // 篮子中的苹果数
 27                int num = 0;
 28                // 篮子中的最多放的苹果数
 29                int count = 5;
 30  
 31                /**
 32                * 生产苹果,往篮子里放
 33                *
 34                * @throws InterruptedException
 35                */
 36                public void produce() throws InterruptedException {
 37                       // 获得锁
 38                       lock.lock();
 39                      System. out.println("Producer get a lock..." );
 40                       try {
 41                             // 判断是否满足生产条件
 42                             while (num == count) {
 43                                    // 如果有苹果,则不生产,放弃锁,进入睡眠
 44                                    // 等待消费者消费
 45                                   System. out.println("Producer sleep..." );
 46                                    consumed.await();
 47                                   System. out.println("Producer awaked..." );
 48                            }
 49                             /* 生产苹果 */
 50                            Thread. sleep(new Random().nextInt(50));
 51                            System. out.println("Producer produced an Apple." );
 52                             num++;
 53                            System. out.println("Producer 篮子里有" + num + "个苹果" );
 54                             // 通知等待produced Condition的线程
 55                             produced.signal();
 56                      } finally {
 57                             lock.unlock();
 58                      }
 59               }
 60  
 61                /**
 62                * 消费苹果,从篮子中取
 63                *
 64                * @throws InterruptedException
 65                */
 66                public void consume() throws InterruptedException {
 67                       // 获得锁
 68                       lock.lock();
 69                      System. out.println("Consumer get a lock..." );
 70                       try {
 71                             // 判断是否满足消费条件
 72                             while (num == 0) {
 73                                    // 如果没有苹果,无法消费,则放弃锁,进入睡眠
 74                                    // 等待生产者生产苹果
 75                                   System. out.println("Consumer sleep..." );
 76                                    produced.await();
 77                                   System. out.println("Consumer awaked..." );
 78                            }
 79                             /* 吃苹果 */
 80                            Thread. sleep(new Random().nextInt(500));
 81                            System. out.println("Consumer consumed an Apple." );
 82                             num--;
 83                            System. out.println("Consumer 篮子里剩" + num + "个苹果" );
 84                             // 发信号唤醒某个等待consumed Condition的线程
 85                             consumed.signal();
 86                      } finally {
 87                             lock.unlock();
 88                      }
 89               }
 90        }
 91  
 92         /**
 93         * 测试Basket程序
 94         */
 95         public static void testBasket() throws Exception {
 96                final Basket basket = new Basket();
 97                // 定义一个producer
 98               Runnable producer = new Runnable() {
 99                       public void run() {
100                             try {
101                                   basket.produce();
102                            } catch (InterruptedException ex) {
103                                   ex.printStackTrace();
104                            }
105                      }
106               };
107  
108                // 定义一个consumer
109               Runnable consumer = new Runnable() {
110                       public void run() {
111                             try {
112                                   basket.consume();
113                            } catch (InterruptedException ex) {
114                                   ex.printStackTrace();
115                            }
116                      }
117               };
118  
119                // 各产生10个consumer和producer
120               ExecutorService service = Executors. newCachedThreadPool();
121                for (int i = 0; i < 10; i++) {
122                      service.execute(producer);
123               }
124                for (int i = 0; i < 10; i++) {
125                      service.execute(consumer);
126               }
127               service.shutdown();
128        }
129  
130         public static void main(String[] args) throws Exception {
131               ConditionTest. testBasket();
132        }
133 }
复制代码
原文地址:https://www.cnblogs.com/zhangyuhang3/p/6872662.html