阻塞隊列常用示例BlockingQueue

一、什麼是阻塞隊列

阻塞隊列是一個隊列,在數據結構中起的作用如下圖:

棧:先進後出,後進先出
隊列:先進先出
阻塞:必須要阻塞/不得不阻塞 

在這裏插入圖片描述
當隊列是空的,從隊列中獲取元素的操作將會被阻塞
當隊列是滿的,從隊列中添加元素的操作將會被阻塞

試圖從空的隊列中獲取元素的線程將會被阻塞,直到其他線程往空的隊列插入新的元素

試圖向已滿的隊列中添加新元素的線程將會被阻塞,直到其他線程從隊列中移除一個或多個元素或者完全清空,使隊列變得空閒起來並後續新增

二、阻塞隊列的作用

在多線程領域:所謂阻塞,在某些情況下會掛起線程(即阻塞),一旦條件滿足,被掛起的線程又會自動被喚起

2.1 爲什麼需要BlockingQueue
好處是我們不需要關心什麼時候需要阻塞線程,什麼時候需要喚醒線程,因爲這一切BlockingQueue都給你一手包辦了

在concurrent包發佈以前,在多線程環境下,我們每個程序員都必須去自己控制這些細節,尤其還要兼顧效率和線程安全,而這會給我們的程序帶來不小的複雜度。

2.2 阻塞隊列的分類

ArrayBlockingQueue:由數組結構組成的有界阻塞隊列
LinkedBlockingQueue:由鏈表結構組成的有界(但大小默認值爲integer.MAX_VALUE)阻塞隊列
PriorityBlockingQueue:支持優先級排序的無界阻塞隊列
DelayQueue:使用優先級隊列實現的延遲無界阻塞隊列
SynchronousQueue:不存儲元素的阻塞隊列,也即單個元素的隊列
LinkedTransferQueue:由鏈表組成的無界阻塞隊列
LinkedBlockingDeque:由鏈表組成的雙向阻塞隊列

2.3 BlockingQueue核心方法

在這裏插入圖片描述
| 拋出異常 | 當阻塞隊列滿時,再往隊列裏add插入元素會拋IllegalStateException:Queue full
當阻塞隊列空時,再往隊列裏remove移除元素會拋NoSuchElementException |
|特殊值|插入方法,成功ture失敗false
移除方法,成功返回出隊列的元素,隊列裏沒有就返回null|
| 一直阻塞 | 當阻塞隊列滿時,生產者線程繼續往隊列裏put元素,隊列會一直阻塞生產者線程直到put數據or響應中斷退出
當阻塞隊列空時,消費者線程試圖從隊列裏take元素,隊列會一直阻塞消費者線程直到隊列可用 |
| 超時退出 | 當阻塞隊列滿時,隊列會阻塞生產者線程一定時間,超過限時後生產者線程會退出 |

三、使用示例
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 阻塞隊列
 */
public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {

        //        List list = new ArrayList();

        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
        //第一組
        //        System.out.println(blockingQueue.add("a"));
        //        System.out.println(blockingQueue.add("b"));
        //        System.out.println(blockingQueue.add("c"));
        //        System.out.println(blockingQueue.element());

        //System.out.println(blockingQueue.add("x"));
        //        System.out.println(blockingQueue.remove());
        //        System.out.println(blockingQueue.remove());
        //        System.out.println(blockingQueue.remove());
        //        System.out.println(blockingQueue.remove());
        //    第二組
        //        System.out.println(blockingQueue.offer("a"));
        //        System.out.println(blockingQueue.offer("b"));
        //        System.out.println(blockingQueue.offer("c"));
        //        System.out.println(blockingQueue.offer("x"));
        //        System.out.println(blockingQueue.poll());
        //        System.out.println(blockingQueue.poll());
        //        System.out.println(blockingQueue.poll());
        //        System.out.println(blockingQueue.poll());
        //    第三組
        //         blockingQueue.put("a");
        //         blockingQueue.put("b");
        //         blockingQueue.put("c");
        //         //blockingQueue.put("x");
        //        System.out.println(blockingQueue.take());
        //        System.out.println(blockingQueue.take());
        //        System.out.println(blockingQueue.take());
        //        System.out.println(blockingQueue.take());

        //    第四組
        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        System.out.println(blockingQueue.offer("a",3L, TimeUnit.SECONDS));

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