併發學習計劃-ArrayBlockingQueue和LinkedBlockingQueue02

weixin_33860553發表於2019-01-28

兩個東西,看名字就知道是先進先出的佇列,不過這個blocking是什麼意思,很顯然這是“塊”的意思,也就是這是一個阻塞佇列。

舉個生活中的例子,籃子裡面最多隻能放5個蘋果,一個人往籃子裡面放,一個人往籃子裡面拿,假設籃子的容量滿了,就要等一個人拿出來之後才能放,籃子空了也要等一個人把蘋果放進去才能拿。

上面的例子有點消費生產者模式的意思。

跟今天我們要說的BlockingQueue有啥關係呢,這兩個BlockingQueue就好像這個籃子一樣。滿了就等有容量的時候再裝,空了就等有東西的時候再拿。

唯一的區別就是,ArrayBlockingQueue的內部是陣列,LinkedBlockingQueue的內部是連結串列。

拿ArrayBlockingQueue舉例子。

如果寫出了下面的程式碼,就完了。

BlockingQueue<String> a = new ArrayBlockingQueue<String>(5);
for (int i = 0; i < 10; i++) {
    try {
        a.put(i + "");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
System.out.println("111");

因為永遠執行不到最後面的列印語句,會永遠卡在那裡,容量只有5,但是要放10個東西。

我們可以這樣做:

BlockingQueue<String> a = new ArrayBlockingQueue<String>(5);
new Thread(new Runnable() {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                a.put(i + "");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}).start();
new Thread(new Runnable() {
    @Override
    public void run() {
        String str;
        try {
            while ((str = a.take()) != null) {
                System.out.println("take : " + str);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}).start();

寫兩個執行緒,一個放一個拿,這樣就不會阻塞了,阻塞的好處就是,可以在一定程度上節約空間。

我們可以在這些佇列中存放執行緒哦,假設有10個任務,5個執行緒,把任務丟進去,讓5個執行緒去執行,哪個執行緒執行完了就去執行下一個任務,任務也可以用佇列儲存起來,這樣也不會弄混。

good idea!

相關文章