JDK5.0 特性-线程 Condition
来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291471.html
1 import java.util.concurrent.ExecutorService; 2 3 import java.util.concurrent.Executors; 4 5 import java.util.concurrent.locks.Condition; 6 7 import java.util.concurrent.locks.Lock; 8 9 import java.util.concurrent.locks.ReentrantLock; 10 11 12 13 /** 14 15 *有时候线程取得lock后需要在一定条件下才能做某些工作,比如经典的Producer和Consumer问题 16 17 *在Java 5.0以前,这种功能是由Object类的wait(),notify()和notifyAll()等方法实现的 18 19 *在5.0里面,这些功能集中到了Condition这个接口实现 20 21 */ 22 23 /** 24 25 * 使用Condition的关键技术点如下: 26 27 * 1.通过Lock的newCondition方法创建Condition的对象 28 29 * 2.Condition的await方法使当前线程进入等待状态,并且释放它占据的Lock,直到有其他的线程唤醒当前线程时,重新占有Lock. 30 31 * 3.Condition的signal方法唤醒其他正在等待该Condition的线程. 32 33 */ 34 35 public class ConditionTest { 36 37 /** 38 39 * 篮子程序,这里为了简化问题,篮子中最多只能有一个苹果 40 41 * Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定 42 43 * 等到Producer往篮子里放了苹果后再去拿来吃。 44 45 * 否则它也需要暂时解锁等Comsumer把苹果吃了才能往篮子里放苹果。 46 47 */ 48 49 public static class Basket{ 50 51 //锁 52 53 Lock lock = new ReentrantLock(); 54 55 //根据锁产生Condition对象 56 57 Condition produced = lock.newCondition(); 58 59 Condition consumed = lock.newCondition(); 60 61 //篮子里的苹果数,最多为1 62 63 int num = 0; 64 65 //生产苹果,往篮子里放 66 67 public void produce() throws InterruptedException{ 68 69 //获得锁 70 71 lock.lock(); 72 73 System.out.println("Producer get a lock..."); 74 75 76 77 try{ 78 79 //判断是否满足生产条件 80 81 while(num == 1){ 82 83 //如果有苹果,则不生产,放弃锁,进入睡眠 84 85 //等待消费者消费 86 87 System.out.println("Producer sleep..."); 88 89 consumed.await(); 90 91 System.out.println("Producer awaked..."); 92 93 } 94 95 //生产苹果 96 97 Thread.sleep(500); 98 99 System.out.println("Producer produced an Apple."); 100 101 num = 1; 102 103 //通知等待produced Condition的线程 104 105 produced.signal(); 106 107 }finally{ 108 109 lock.unlock(); 110 111 } 112 113 } 114 115 //消费苹果,从篮子里取 116 117 public void consume() throws InterruptedException{ 118 119 //获得锁 120 121 lock.lock(); 122 123 System.out.println("Consumer get a lock..."); 124 125 try{ 126 127 //判断是否满足消费条件 128 129 while(num == 0){ 130 131 //如果没有苹果,无法消费,则放弃锁,进入睡眠 132 133 //等待生产者生产苹果 134 135 System.out.println("Consumer sleep..."); 136 137 produced.await(); 138 139 System.out.println("Consumer awaked..."); 140 141 } 142 143 //吃苹果 144 145 Thread.sleep(500); 146 147 System.out.println("Consumer consumed an Apple."); 148 149 num = 0; 150 151 //发信号唤醒某个等待consumed Condition的线程 152 153 consumed.signal(); 154 155 } finally { 156 157 lock.unlock(); 158 159 } 160 161 } 162 163 } 164 165 //测试Basket程序 166 167 public static void testBasket() throws Exception{ 168 169 final Basket basket = new Basket(); 170 171 //定义一个producer 172 173 Runnable producer = new Runnable(){ 174 175 public void run() { 176 177 try{ 178 179 basket.produce(); 180 181 }catch(InterruptedException ex){ 182 183 ex.printStackTrace(); 184 185 } 186 187 } 188 189 }; 190 191 //定义一个consumer 192 193 Runnable consumer = new Runnable(){ 194 195 public void run(){ 196 197 try{ 198 199 basket.consume(); 200 201 }catch(InterruptedException ex){ 202 203 ex.printStackTrace(); 204 205 } 206 207 } 208 209 }; 210 211 //各生产3个consumer和producer 212 213 ExecutorService service = Executors.newCachedThreadPool(); 214 215 for(int i = 0; i <3; i++){ 216 217 service.submit(producer); 218 219 } 220 221 for(int i = 0;i<3;i++){ 222 223 service.submit(consumer); 224 225 } 226 227 service.shutdown(); 228 229 } 230 231 public static void main(String... args)throws Exception{ 232 233 ConditionTest.testBasket(); 234 235 } 236 237 } 238 239