标签:pre current title shu lock main rgs runnable src
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 }
标签:pre current title shu lock main rgs runnable src
原文地址:http://www.cnblogs.com/zhangyuhang3/p/6872662.html