一。java
1.有時線程取得鎖時須要在必定條件下才能作某些工做,好比經典的Producer、Consumer問題。app
2.在jdk 1.5千,這種功能是經過Object類的wait notify和notifyall實現的,以後能夠用condition實現。ide
二。測試
測試代碼以下,注意註釋部分代碼。或者直接參考arrayblickingqueue的源碼put和take方法線程
public class ConditonTest { public static class Basket { Lock lock = new ReentrantLock(); Condition produceCondition = lock.newCondition(); Condition consumeCondition = lock.newCondition(); int num = 0; public void consume() throws InterruptedException { lock.lock(); System.out.println("consumer get a lock"); try { while (num == 0) { // 等於0的話不消費蘋果 System.out.println("Consumer sleep"); try { consumeCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("consumer awaked"); } Thread.sleep(500); System.out.println("consumer consumed an apple"); num = 0; produceCondition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("lock unlock"); lock.unlock(); } } public void produce() throws InterruptedException { lock.lock(); System.out.println("producer get a lock"); try { while (num == 1) { // 等於1的話不生產蘋果 System.out.println("producer sleep"); try { produceCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("producer awaked"); } Thread.sleep(500); System.out.println("producer produced an apple"); num = 1; consumeCondition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("lock unlock"); lock.unlock(); } } } public static void testBasket(){ final Basket bask=new Basket(); Runnable producer=new Runnable() { @Override public void run() { try { bask.produce(); } catch (InterruptedException e) { e.printStackTrace(); } } }; Runnable consumer=new Runnable() { @Override public void run() { try { bask.consume(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; /*ExecutorService executorService=Executors.newCachedThreadPool(); for(int i=0;i<3;i++){ executorService.submit(consumer); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i<3;i++){ executorService.submit(producer); }*/ new Thread(consumer).start(); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } new Thread(producer).start(); } public static void main(String[] args) { testBasket(); } }