Java阻塞隊列的實現(xiàn)

阻塞隊列(BlockingQueue)是一個支持兩個附加操作的隊列。這兩個附加的操作是:在隊列為空時,獲取元素的線程會等待隊列變?yōu)榉强?。當隊列滿時,存儲元素的線程會等待隊列可用。阻塞隊列常用于生產(chǎn)者和消費者的場景,生產(chǎn)者是往隊列里添加元素的線程,消費者是從隊列里拿元素的線程。阻塞隊列就是生產(chǎn)者存放元素的容器,而消費者也只從容器里拿元素。

阻塞隊列提供了四種處理方法:

方法\處理方式 拋出異常 返回特殊值 一直阻塞 超時退出
插入方法 add(e) offer(e) put(e) offer(e,time,unit)
移除方法 remove() poll() take() poll(time,unit)
檢查方法 element() peek() 不可用 不可用
拋出異常:是指當阻塞隊列滿時候,再往隊列里插入元素,會拋出IllegalStateException(“Queue full”)異常。當隊列為空時,從隊列里獲取元素時會拋出NoSuchElementException異常 。
返回特殊值:插入方法會返回是否成功,成功則返回true。移除方法,則是從隊列里拿出一個元素,如果沒有則返回null
一直阻塞:當阻塞隊列滿時,如果生產(chǎn)者線程往隊列里put元素,隊列會一直阻塞生產(chǎn)者線程,直到拿到數(shù)據(jù),或者響應中斷退出。當隊列空時,消費者線程試圖從隊列里take元素,隊列也會阻塞消費者線程,直到隊列可用。
超時退出:當阻塞隊列滿時,隊列會阻塞生產(chǎn)者線程一段時間,如果超過一定的時間,生產(chǎn)者線程就會退出。

  1. Java里的阻塞隊列

JDK7提供了7個阻塞隊列。分別是

ArrayBlockingQueue :一個由數(shù)組結構組成的有界阻塞隊列。
LinkedBlockingQueue :一個由鏈表結構組成的有界阻塞隊列。
PriorityBlockingQueue :一個支持優(yōu)先級排序的無界阻塞隊列。
DelayQueue:一個使用優(yōu)先級隊列實現(xiàn)的無界阻塞隊列。
SynchronousQueue:一個不存儲元素的阻塞隊列。
LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。
LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。

簡單理解:

阻塞隊列與普通隊列的區(qū)別在于,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列,下圖展示了如何通過阻塞隊列來合作:

線程1往阻塞隊列中添加元素,而線程2從阻塞隊列中移除元素
從5.0開始,JDK在java.util.concurrent包里提供了阻塞隊列的官方實現(xiàn)。盡管JDK中已經(jīng)包含了阻塞隊列的官方實現(xiàn),但是熟悉其背后的原理還是很有幫助的。

package thread.BlockingQueue;

import sun.awt.CustomCursor;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

public class BlockingQueueTest {
    /**
     * 生產(chǎn)者
     */
    public static class  Producer implements Runnable{
        private final BlockingQueue<Integer> blockingQueue;
        //同步變量 volatile
        private volatile boolean flag;
        private Random random;

        public Producer(BlockingQueue<Integer> blockingQueue){
            this.blockingQueue = blockingQueue;
            flag=false;
            random=new Random();
        }


        @Override
        public void run() {
            while (!flag){
                int info = random.nextInt();
                try {
                    blockingQueue.put(info);
                    System.out.println(Thread.currentThread().getName()+"---->Producer"+info);
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }

        public void shutDown(){
            flag =  true;
        }
    }

    public static class Consumer implements Runnable{

        private final BlockingQueue<Integer> blockingQueue;
        private volatile boolean flag;
        public Consumer(BlockingQueue<Integer> blockingQueue){
                this.blockingQueue = blockingQueue;
        }


        @Override
        public void run() {
            while (!flag){
                int info;
                try {
                    info = blockingQueue.take();
                    System.out.println(Thread.currentThread().getName()+" --->consumer "+info);
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }


        }
        public void shutDown(){
            flag=true;
        }

        public static void main(String[] args) {
            BlockingQueue<Integer> blockingQueue = new LinkedBlockingDeque<Integer>(10);
            Producer producer = new Producer(blockingQueue);
            Consumer consumer = new Consumer(blockingQueue);
            //創(chuàng)建5個生產(chǎn)者,5個消費者
            for(int i = 0; i<10;i++){
                //System.out.println("-----------------------"+i+"-----------------------");
                if(i<5){
                    new Thread(producer,"producer"+i).start();
                }else{
                    new Thread(consumer,"consumer"+(i-5)).start();
                }

            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            producer.shutDown();
            consumer.shutDown();


        }
    }
}

輸出

producer0---->Producer-1129494571
producer1---->Producer1335810196
producer2---->Producer251379931
producer3---->Producer-1038309758
producer4---->Producer1259289873
consumer0 --->consumer -1129494571
consumer1 --->consumer 1335810196
consumer2 --->consumer 251379931
consumer3 --->consumer -1038309758
consumer4 --->consumer 1259289873
producer0---->Producer2080589140
producer1---->Producer-226440319
producer3---->Producer-1251256190
producer2---->Producer1570622388
producer4---->Producer-1730471428
consumer1 --->consumer 2080589140
consumer0 --->consumer -226440319
consumer2 --->consumer -1251256190
consumer3 --->consumer 1570622388
consumer4 --->consumer -1730471428
producer1---->Producer-1117165496
producer0---->Producer1429895528
producer4---->Producer-12279844
producer2---->Producer1148382323
producer3---->Producer859079924
consumer0 --->consumer -1117165496
consumer1 --->consumer 1429895528
consumer2 --->consumer -12279844
consumer3 --->consumer 1148382323
consumer4 --->consumer 859079924
producer0---->Producer697920454
producer1---->Producer-1472263430
producer3---->Producer1862992273
producer2---->Producer-431825769
producer4---->Producer-170876869
consumer0 --->consumer -1472263430
consumer1 --->consumer 697920454
consumer2 --->consumer 1862992273
consumer3 --->consumer -431825769
consumer4 --->consumer -170876869
producer0---->Producer661728231
producer1---->Producer-1580613248
producer4---->Producer286944580
producer2---->Producer-1756199503
producer3---->Producer-515489831
consumer1 --->consumer 661728231
consumer0 --->consumer -1580613248
consumer3 --->consumer 286944580
consumer2 --->consumer -1756199503
consumer4 --->consumer -515489831
producer0---->Producer-824253958
producer1---->Producer-718043703
producer2---->Producer613726687
producer4---->Producer1562017654
producer3---->Producer2113604249
consumer3 --->consumer -718043703
consumer0 --->consumer -824253958
consumer1 --->consumer 613726687
consumer2 --->consumer 2113604249
consumer4 --->consumer 1562017654
producer1---->Producer-1926369295
producer0---->Producer1160592917
producer3---->Producer261832181
producer4---->Producer45296507
producer2---->Producer2027140406
consumer3 --->consumer -1926369295
consumer1 --->consumer 1160592917
consumer2 --->consumer 261832181
consumer0 --->consumer 45296507
consumer4 --->consumer 2027140406
producer1---->Producer268940344
producer0---->Producer-680320907
producer3---->Producer1376218456
producer4---->Producer-1303516038
producer2---->Producer-415045622
consumer3 --->consumer -680320907
consumer2 --->consumer 268940344
consumer1 --->consumer 1376218456
consumer0 --->consumer -1303516038
consumer4 --->consumer -415045622
producer1---->Producer-373379865
producer0---->Producer1045950051
producer3---->Producer-282195419
producer4---->Producer2072455342
producer2---->Producer730482583
consumer3 --->consumer 1045950051
consumer0 --->consumer -373379865
consumer1 --->consumer -282195419
consumer2 --->consumer 2072455342
consumer4 --->consumer 730482583
producer0---->Producer1099300076
producer1---->Producer-438856015
producer3---->Producer-827705749
producer4---->Producer-489876804
producer2---->Producer-770066015
consumer3 --->consumer 1099300076
consumer2 --->consumer -438856015
consumer0 --->consumer -489876804
consumer1 --->consumer -827705749
consumer4 --->consumer -770066015
producer3---->Producer796772527
producer4---->Producer-1424401866
producer1---->Producer2104464948
producer0---->Producer-843892940
producer2---->Producer167062848
consumer3 --->consumer -1424401866
consumer1 --->consumer 796772527
consumer0 --->consumer 2104464948
consumer2 --->consumer -843892940
consumer4 --->consumer 167062848
producer0---->Producer2062676055
producer1---->Producer-1075270028
producer4---->Producer830173242
producer3---->Producer-288128280
producer2---->Producer-1316693459
consumer3 --->consumer 2062676055
consumer2 --->consumer -1075270028
consumer1 --->consumer -1316693459
consumer0 --->consumer 830173242
consumer4 --->consumer -288128280
producer0---->Producer-1740245319
producer1---->Producer-2079049898
producer4---->Producer-1382219742
producer3---->Producer663598513
producer2---->Producer-1374412157
consumer3 --->consumer -1740245319
consumer4 --->consumer -2079049898
consumer0 --->consumer -1382219742
consumer1 --->consumer 663598513
consumer2 --->consumer -1374412157
producer3---->Producer923120722
producer4---->Producer1267254300
producer2---->Producer-355170922
producer0---->Producer-384775396
producer1---->Producer1978595907
consumer4 --->consumer -355170922
consumer3 --->consumer 923120722
consumer2 --->consumer 1267254300
consumer1 --->consumer 1978595907
consumer0 --->consumer -384775396
producer4---->Producer301647653
producer3---->Producer2070336417
consumer4 --->consumer 301647653
consumer3 --->consumer 2070336417
producer1---->Producer130543442
producer0---->Producer33891840
producer2---->Producer199012254
consumer2 --->consumer 130543442
consumer1 --->consumer 33891840
consumer0 --->consumer 199012254
producer4---->Producer2034412277
consumer3 --->consumer 2034412277
consumer4 --->consumer 1684896549
producer3---->Producer1684896549
producer2---->Producer-823024779
producer0---->Producer1245530223
producer1---->Producer1426270482
consumer2 --->consumer -823024779
consumer1 --->consumer 1245530223
consumer0 --->consumer 1426270482
consumer3 --->consumer -657670721
producer4---->Producer-657670721
consumer0 --->consumer -514396374
producer1---->Producer-514396374
consumer1 --->consumer -1938139766
producer0---->Producer-1938139766
consumer2 --->consumer -1416028874
producer2---->Producer-1416028874
producer3---->Producer386535270
consumer4 --->consumer 386535270
producer4---->Producer-280750862
consumer3 --->consumer -280750862
producer0---->Producer-1610461450
consumer1 --->consumer -1610461450
producer1---->Producer-906749135
consumer0 --->consumer -906749135
consumer4 --->consumer -1239123559
producer3---->Producer-1239123559
producer2---->Producer596392102
consumer2 --->consumer 596392102
producer4---->Producer144344294
consumer3 --->consumer 144344294
producer2---->Producer-239480864
consumer2 --->consumer -239480864
producer3---->Producer-1952232640
consumer4 --->consumer -1952232640
consumer0 --->consumer -138057655
producer1---->Producer-138057655
consumer1 --->consumer -1277497082
producer0---->Producer-1277497082

Process finished with exit code 0

即可看到生產(chǎn)者生產(chǎn)的 被消費者消費了,與普通隊列不同的是
隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容