wait()、notify()、notifyAll()方法的理解

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();
            }
        }
    }

}
相關文章
相關標籤/搜索