EverTriely

导航

Java之多线程开发时多条件Condition接口的使用

转:http://blog.csdn.net/a352193394/article/details/39454157

我们在多线程开发中,可能会出现这种情况。就是一个线程需要另外一个线程满足某某条件才能继续运行,或者需

要其他线程满足好几个条件才能运行,对于这样的多条件的多线程并发,我们如何控制好各个线程之间的关系,使他们

能很好的处理冲突不至于相互出现问题呢,下面我们来介绍一下Java提供的Condition这个接口,这个接口很好的实现了

这种需求。

对于这个问题最经典的例子就是生产者消费者模型,生产者当缓冲区满的时候不生产商品知道缓冲区有空余,消费

者当缓冲区为0 的时候不拿商品,直到生产者向缓冲区放入商品,下面我们使用Conditon这个接口来实现这样的需求。

 

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

 

 
 

posted on 2015-10-26 21:54  EverTriely  阅读(530)  评论(0编辑  收藏  举报