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 }