七大BlockingQueue

 阻塞隊列與普通隊列的區別在於,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列裏添加元素的操作會被阻塞。

ArrayBlockingQueue

//數組結構組成的有界阻塞隊列
public class ArrayBlockingQueue_Demo {
    public static void main(String[]args)throws InterruptedException{
        //大小固定,有邊的。
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(17);
        queue.offer("Liu");
        queue.offer("Jun");
        queue.offer("South");
        // add() 隊尾添加元素,成功返回 true ,失敗拋出異常。
        boolean add = queue.add("add");
        // offer() 隊尾新添加元素。返回true表示添加成功,false表示添加失敗,不會拋出異常。
        boolean offer1 = queue.offer("offer");
        // offer() 隊尾新添加元素,如果隊列中沒有可用空間,當前線程就等待,如果等待時間超過timeout了,那麼返回false,表示添加失敗。
        boolean offer2 = queue.offer("offer",3,TimeUnit.SECONDS);
        // put() 向隊列末尾新添加元素,如果隊列已滿,當前線程就等待(阻塞線程)。響應中斷異常,無返回值。
        queue.put("put");


        // remove() 移除頭部元素,如果爲null則拋出異常,也可移除已知元素。
        boolean remove = queue.remove("remove");
        // poll() 移除頭部元素並返回。如果null不會拋異常,會返回null。
        String poll1 =  queue.poll();
        // poll() 返回並移除隊列第一個元素,如果隊列是空的,就前線程就等待。 如果等待時間超過timeout了,那麼返回false,表示獲取元素失敗
        String poll2 = queue.poll(3,TimeUnit.SECONDS);
        // element() 獲取頭部元素,如果是null,拋出異常,不會刪除元素。
        String element = queue.element();
        // peek() 獲取頭部元素,不會刪除元素。
        String peek = queue.peek();
        // take() 如果隊列爲空則等待,否則移除頭元素。
        String take = queue.take();

        // remainingCapacity() 還剩多少空間
        int size = queue.remainingCapacity();
    }
}

LinkedBlockingDeque

//鏈表結構組成的雙向阻塞隊列
public class LinkedBlockingDeque_Demo {
    public static void main(String[]args)throws InterruptedException{
        //自動擴容
        LinkedBlockingDeque<String> queue = new LinkedBlockingDeque();
        queue.offer("Jun");
        queue.offer("South");
        //add() 如果隊列已滿,報java.lang.IllegalStateException: Queue full 錯誤。
        boolean add = queue.add("add");
        //offer() 如果隊列已滿,程序正常運行,只是不再新增元素。
        boolean offer1 = queue.offer("offer1");
        boolean offer2 = queue.offer("offer2",2, TimeUnit.SECONDS);
        //put() 如果隊列已滿,阻塞。
        queue.put("put");


        //remove() 移除頭部元素,如果爲null拋出異常。
        boolean remove = queue.remove("remove");
        //poll() 移除頭部元素,隊列爲空時返回null。
        String poll = queue.poll();
        //獲取頭部元素,如果是null則拋異常。不會刪除元素。
        String element = queue.element();
        //獲取頭部元素,不刪除元素。隊列爲空時返回null。
        String peek = queue.peek();
        // 移除頭部元素。當隊列爲空,阻塞。
        String take = queue.take();
    }
}

LinkedBlockingQueue

//鏈表結構組成的有界阻塞隊列
public class LinkedBlockingQueue_Demo {
    public static void main(String[]args)throws InterruptedException{
        // 如果給定長度,則是定長。若不給定長度,會自動擴容。
        LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>();
        queue.offer("Jun");
        queue.offer("South");
        //add() 如果隊列已滿,報java.lang.IllegalStateException: Queue full 錯誤。
        boolean add = queue.add("add");
        //offer() 如果隊列已滿,程序正常運行,只是不再新增元素。
        boolean offer1 = queue.offer("offer1");
        boolean offer2 = queue.offer("offer2",2, TimeUnit.SECONDS);
        //put() 如果隊列已滿,阻塞。
        queue.put("put");


        //remove() 移除頭部元素,如果爲null拋出異常。
        boolean remove = queue.remove("remove");
        //poll() 移除頭部元素,隊列爲空時返回null。
        String poll = queue.poll();
        //獲取頭部元素,如果是null則拋異常。不會刪除元素。
        String element = queue.element();
        //獲取頭部元素,不刪除元素。隊列爲空時返回null。
        String peek = queue.peek();
        // 移除頭部元素。當隊列爲空,阻塞。
        String take = queue.take();
    }
}

LinkedTransferQueue

//鏈表結構組成的無界阻塞隊列
public class LinkedTransferQueue_Demo {
    public static void main(String[]args)throws InterruptedException{
        //自動擴容
        LinkedTransferQueue<String> queue = new LinkedTransferQueue<>();

        //add() 隊尾插元素,永遠返回true。
        boolean add = queue.add("add");
        //offer() 隊尾插元素,永遠返回true。
        boolean offer1 = queue.offer("offer1");
        boolean offer2 = queue.offer("offer2",2, TimeUnit.SECONDS);
        //put() 隊尾插元素,永遠返回true。
        queue.put("put");
        //在隊尾插元素,沒有被消費,則等待。
        queue.transfer("transfer");


        //remove() 移除頭部元素,如果爲null拋出異常。
        boolean remove = queue.remove("remove");
        //poll() 移除頭部元素,隊列爲空時返回null。
        String poll = queue.poll();
        //獲取頭部元素,如果是null則拋異常。不會刪除元素。
        String element = queue.element();
        //獲取頭部元素,不刪除元素。隊列爲空時返回null。
        String peek = queue.peek();
        // 移除頭部元素。當隊列爲空,阻塞。
        String take = queue.take();
    }
}

PriorityBlockingQueue

//支持優先級排序的無界阻塞隊列
public class PriorityBlockingQueue_Demo {
    public static void main(String[]args)throws InterruptedException{
        //可指定長度,會自動擴容,無邊。
        PriorityBlockingQueue<String> queue = new PriorityBlockingQueue<String>();
        queue.offer("Jun");
        queue.offer("Liu");
        queue.offer("South");
        // offer() 成功返回true,除非內存溢出否則不會返回false。
        boolean offer1 =  queue.offer("offer1");
        boolean offer2 =  queue.offer("offer2",3, TimeUnit.SECONDS);
        // add() 調用 offer() 方法
        boolean add = queue.add("add");
        // put() 調用offer() 方法,無返回值。
        queue.put("put");


        // remove() 刪除頭部元素或指定刪除元素,如果爲null則拋異常。
        boolean remove = queue.remove("offer1");
        // poll() 移除頭部元素並返回。
        String poll = queue.poll();
        // element() 獲取頭部元素,如果是null,拋出異常,不會刪除元素。
        String element = queue.element();
        // peek() 獲取頭部元素,不會刪除元素。
        String peek = queue.peek();
        // take() 如果隊列爲空則等待,否則移除頭元素。
        String take = queue.take();

    }
}

SynchronousQueue

//沒有容量,是無緩衝等待隊列,是一個不存儲元素的阻塞隊列,會直接將任務交給消費者,必須等隊列中的添加元素被消費後才能繼續添加新的元素。
//插入操作put必須等移除操作take,反之亦然。
//不存儲元素的的阻塞隊列
public class SynchronousQueue_Demo {
    public static void main(String[]args)throws  InterruptedException{
        SynchronousQueue<String> queue = new SynchronousQueue<String>();
        // offer() 往queue裏放一個element後立即返回,如果碰巧這個element被另一個thread取走了,offer方法返回true,認爲offer成功;否則返回false。
        boolean offer1 =  queue.offer("offer1");
        // offer(3, TimeUnit.SECONDS) 往queue裏放一個element但是等待指定的時間後才返回,返回的邏輯和offer()方法一樣。
        boolean offer2 = queue.offer("offer2",2, TimeUnit.SECONDS);
        // put() 往queue放進去一個element以後就一直wait直到有其他thread進來把這個element取走。
        queue.put("put");


        // remove()和removeAll() 永遠是false。
        String remove = queue.remove();
        // peek() 永遠返回null。
        String peek = queue.peek();
        // poll() 取出並且remove掉queue裏的element(認爲是在queue裏的。。。),只有到碰巧另外一個線程正在往queue裏offer數據或者put數據的時候,該方法纔會取到東西。否則立即返回null。
        String poll = queue.poll();
        // take() 取出並且remove掉queue裏的element(認爲是在queue裏的。。。),取不到東西他會一直等。
        String take = queue.take();
        // iterator() 永遠返回空,因爲裏面沒東西。
        // isEmpty()永遠是true。
        // remainingCapacity() 永遠是0。
    }
}

DelayQueue

/*
DelayQueue 是一個無界阻塞隊列,要添加進去的元素必須實現 Delayed 接口,只有在延遲期滿時才能從中提取元素。
該隊列的頭部 是延遲期滿後保存時間最長的 Delayed 元素。
如果延遲都還沒有期滿,則隊列沒有頭部,並且 poll 將返回 null。
當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於等於 0 的值時,表示該元素到期了。
無法使用 take 或 poll 移除未到期的元素,也不會將這些元素作爲正常元素對待。例如,size 方法同時返回到期和未到期元素的計數。
此隊列不允許使用 null 元素。*/
//使用優先級隊列實現的無界阻塞隊列
public class DelayQueue_Demo{
static class DelayElement<E> implements Delayed{
    private final E e;
    private long start = System.currentTimeMillis();
    private final long time;
    public DelayElement(E e, long time) {
        this.e = e;
        this.time = time + start;
    }
    static <T> DelayElement<T> of(T e,long delay){
        return new DelayElement<>(e,delay);
    }
    /**
     * 需要實現的接口,獲得延遲時間   用過期時間-當前時間
     * @param unit
     */
    public long getDelay(TimeUnit unit) {
        long diff = time - System.currentTimeMillis();
        return unit.convert(diff,TimeUnit.MILLISECONDS);
    }
    /**
     * 用於延遲隊列內部比較排序   當前時間的延遲時間 - 比較對象的延遲時間
     * @param delayedObject
     */
    public int compareTo(Delayed delayedObject) {
        DelayElement that = (DelayElement) delayedObject;
        if (this.time < that.getExpireTime()){
            return  -1;
        }else if (this.time > that.getExpireTime()){
            return 1;
        }else {
            return 0;
        }
    }
    public E getData(){
        return e;
    }
    public long getExpireTime(){
        return time;
    }
}
    public static void main(String[]args)throws InterruptedException{
        DelayQueue<DelayElement<String>> queue = new DelayQueue();
        //offer() 隊位插元素,如果爲null則拋異常。
        boolean offer = queue.offer(null);
        // add() 隊位插元素,如果爲null則拋異常。
        boolean add = queue.add(DelayElement.of("add",1000));
        // put() 隊位插元素,如果爲null則拋異常。
        queue.put(DelayElement.of("add",1000));


        // remove() 移除頭部元素,爲null則拋異常。
        DelayElement remove = queue.remove();
        // poll() 移除頭部元素並返回。
        DelayElement poll = queue.poll();
        // element() 獲取頭部元素,如果是null則拋異常。不會刪除元素。
        DelayElement element = queue.element();
        // peek() 獲取頭部元素,不會刪除。
        DelayElement peek = queue.peek();
        // take() 獲取頭部元素,有就拿走,沒有就阻塞等待。
        DelayElement take = queue.take();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章