Java阻塞隊列—BlockingQueue

參考:https://www.cnblogs.com/KingIceMou/p/8075343.htmlhtml

BlockingQueue是一個阻塞隊列接口,BlockingQueue基於隊列容器實現了插入和取出數據的阻塞,若是隊列中沒有數據時,取出數據的操做被阻塞直到隊列中有數據能被取出;若是隊列中數據已經填滿,則插入數據的操做將被阻塞,直到隊列中有空位可以插入。BlockingQueue實現是線程安全的,全部排隊方法都使用內部鎖或其餘形式的併發控制以原子方式實現其效果,除非在實現中另有說明。基於以上特性咱們能夠很輕鬆的實現生產者-消費者模型。java

BlockingQueue主要有如下方法:數組

//向隊列中添加一個元素,成功返回true;該元素不能爲null,若是隊列已滿則拋出IllegalStateException
        boolean add(E e);

        //向隊列中添加一個元素,成功返回true;該元素不能爲null,若是隊列已滿則返回false
        boolean offer(E e);

        //向隊列中添加一個元素,成功返回true;該元素不能爲null,若是隊列已滿則調用此方法的線程被阻塞等待timeout時間,若是超過了timeout還不能入隊則返回false,若是等待過程被中斷則拋出InterruptedException
        boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;

        //向隊列中添加一個元素,成功返回true;該元素不能爲null,若是隊列已滿則調用此方法的線程被阻塞等待,直到隊列中裏面有空間再入隊,若是等待過程被中斷則拋出InterruptedException 
        void put(E e) throws InterruptedException;

        //取出隊列中的頭部元素,若是隊列爲空則調用此方法的線程被阻塞等待,直到有元素能被取出,若是等待過程被中斷則拋出InterruptedException
        E take() throws InterruptedException;

        //取出隊列中的頭部元素,若是隊列爲空返回null
        E poll();

        //取出隊列中的頭部元素,若是隊列爲空則調用此方法的線程被阻塞等待timeout時間,若是超過了timeout尚未元素能被取出則返回null,若是等待過程被中斷則拋出InterruptedException
        E poll(long timeout, TimeUnit unit) throws InterruptedException;

        //返回隊列中的頭部元素,但不從隊列中移除該元素,若是隊裏爲空則返回null
        E peek();

        //返回隊列的剩餘容量,咱們不該該用該方法來判斷咱們能不能插入成功,由於可能另外一個線程已經插入了
        int remainingCapacity();

        //從隊列中刪除指定元素,若是該元素存在則刪除該元素並返回true,不然返回false;注意若是隊裏中存在多個相同元素,該方法只會刪除離頭最近的那一個
        boolean remove(Object o);

        //判斷隊列中是否存當前元素
        boolean contains(Object o);

        //將隊列中全部元素取出來放到集合c中
        drainTo(Collection<? super E> c)

BlockingQueue的主要實現有:ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue這幾種,他們之間須要注意的幾點是:安全

  1. ArrayBlockingQueue:基於數組實現,初始化時必須指定隊列長度,插入數據和取出數據共用同一個鎖對象。
  2. LinkedBlockingQueue:基於鏈表實現,初始化能夠不指定隊列長度(默認爲Integer.MAX_VALUE,可能發生內存耗盡的狀況,因此經量在初始化時指定隊列長度),插入數據和取出數據採用獨立的鎖對象。
  3. DelayQueue中的元素只有當其指定的延遲時間到了,纔可以從隊列中獲取到該元素。DelayQueue是一個沒有大小限制的隊列,所以往隊列中插入數據永遠不會被阻塞,而只有獲取數據纔會被阻塞。
  4. PriorityBlockingQueue基於優先級的阻塞隊列(優先級的判斷經過構造函數傳入的Compator對象來決定),但須要注意的是PriorityBlockingQueue並不會阻塞數據生產者,而只會在沒有可消費的數據時,阻塞數據的消費者。所以使用的時候要特別注意,插入數據的速度絕對不能快於取出消費數據的速度,不然容易發生內存耗盡的狀況
相關文章
相關標籤/搜索