wait()表示把線程掛起,掛起的時候會自動釋放鎖。數組
notify() 隨機的選擇一個在指定對象上掛起的線程激活。緩存
notifyAll() 激活指定對象上掛起的全部線程測試
條件隊列:一組等待線程集合,可以經過某種方式來等待對應的條件爲真。條件隊列中的元素是一個正在等待相關條件的線程。this
經過條件隊列構建高可響應的狀態依賴類,條件等待存在三元關係 加鎖、wait、一個條件謂詞(包含多個狀態變量) ,狀態變量由一個鎖保護spa
在測試條件謂語以前必須先得到對象的鎖。鎖對象和條件隊列對象(即調用wait()和notify()方法的對象)必須是同一個對象。線程
以下實現自定義有界緩存實現code
基類代碼對象
package com.lifeStudy.algorith; public abstract class BaseBoundedBuffer<V> { private final V[] buf; private int tail; private int head; private int count; protected BaseBoundedBuffer(int capacity) { //還能夠經過直接new Object[]數組,等到須要具體化時候才 強制轉換單個元素 buf = (V[]) new Object[capacity];//泛型擦除,其實就是(Object[])轉換 } protected synchronized final void doPut(V v) { buf[tail] = v; if (++tail == buf.length) { tail = 0; } count++; } protected synchronized final V doTake() { V rs = buf[head]; buf[head] = null; if (++head == buf.length) { head = 0; } count--; return rs; }
//下面是兩個狀態變量,隊列是否滿;隊列是否爲空 經過內置鎖對象this public synchronized final boolean isFull() { return count == buf.length; } public synchronized final boolean isEmpty() { return count == 0; } }
經過wait()實現條件隊列blog
package com.lifeStudy.algorith; public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {//條件隊列 protected BoundedBuffer(int capacity) { super(capacity); } public synchronized void put(V v) throws InterruptedException { while (isFull()) { System.out.println(Thread.currentThread().getId() + " put競爭失敗,掛起"); this.wait(); System.out.println(Thread.currentThread().getId() + " put被喚醒,二次激活"); } doPut(v); this.notifyAll();//喚醒全部在this對象上掛起的線程 } public synchronized V take() throws InterruptedException { while (isEmpty()) { System.out.println(Thread.currentThread().getId() + " get競爭失敗,掛起"); this.wait();//線程掛起,放開鎖synchronized中this對象。 System.out.println(Thread.currentThread().getId() + " get被喚醒,二次激活"); } V v = doTake(); this.notifyAll();//喚醒全部在this對象上掛起的線程 return v; } public static void main(String... args) throws InterruptedException { BoundedBuffer<Integer> integerBoundedBuffer = new BoundedBuffer<Integer>(12); // new Thread(new Consummer(integerBoundedBuffer)).start(); // TimeUnit.SECONDS.sleep(10); new Thread(new Producer(integerBoundedBuffer)).start(); //經過下面能夠看到 調用wait掛起線程時會釋放鎖. // new Thread(new Producer(integerBoundedBuffer)).start(); } private static class Consummer implements Runnable { private final BoundedBuffer bf; public Consummer(BoundedBuffer bf) { this.bf = bf; } public void run() { try { while (true) { bf.take(); System.out.println("get"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } private static class Producer implements Runnable { private final BoundedBuffer bs; protected Producer(BoundedBuffer bs) { this.bs = bs; } public void run() { try { while (true) { bs.put(123); System.out.println("put"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } }