1.常用的阻塞隊列有哪些又活?
ArrayBlockingQueue佃却、LinkedBlockingQueue、DelayQueue萎攒、SynchronousQueue 、PriorityQueue等
2.它們各自的區(qū)別是什么矛绘?
常見的阻塞隊列 | 數(shù)據(jù)結(jié)構(gòu) | 是否有界 | 線程安全 | 使用場景 | 如何阻塞 |
---|---|---|---|---|---|
ArrayBlockingQueue | 數(shù)組 | 有界 | 使用ReentrantLock保證出入隊線程安全 | 一般用于生產(chǎn)數(shù)據(jù)固定的場景 | 1.當(dāng)隊列為空耍休,take操作會阻塞;poll操作加上超時時間也會阻塞蔑歌,直到超時后返回null 2.當(dāng)隊列滿的時候羹应,put操作會阻塞;offer操作加上超時時間也會阻塞次屠,直到超時后返回false |
LinkedBlockingQueue | 鏈表 | 無界 | 使用ReentrantLock分別作為讀寫鎖保證出入隊線程安全 | 適合對生產(chǎn)的數(shù)據(jù)大小不定(時高時低)园匹,數(shù)據(jù)量較大的場景 | 與 ArrayBlockingQueue 的阻塞原理相似 |
PriorityBlockingQueue | 二叉堆 | 無界 | 使用ReentrantLock保證出入隊線程安全 | 排序阻塞操作 | 隊列是無界的,所以添加元素不會阻塞劫灶。只有當(dāng)隊列為空的時候裸违,take操作會阻塞;poll操作加上超時時間也會阻塞本昏,直到超時后返回null |
DelayQueue | 二叉堆 | 無界 | 使用ReentrantLock保證出入隊線程安全 | 延遲阻塞操作 | 與 PriorityBlockingQueue 的阻塞原理相似 |
SynchronousQueue | 隊列或堆棧 | 無容量概念 | 使用CAS保證出入隊線程安全 | CachedThreadPool線程池使用 | 當(dāng)前操作與隊列或堆棧中第一個數(shù)據(jù)操作一樣的話就會一直阻塞供汛,只有當(dāng)隊列中兩個操作是互補的狀態(tài)才會出隊 |
3.無鎖隊列的原理是什么?
SynchronousQueue 隊列是無鎖隊列涌穆,其內(nèi)部是使用CAS自旋操作保證線程安全
4.延遲阻塞隊列的原理是什么怔昨?
DelayQueue 底層使用了 PriorityQueue 優(yōu)先級隊列,而 PriorityQueue 實際上一個二叉堆結(jié)構(gòu)宿稀,通過比較堆內(nèi)元素過期時間趁舀,將堆內(nèi)最快過期的元素放在堆頭,以保證每次獲取的元素是最二叉堆中最快過期的元素
5.String變量可以放在 DelayQueue 隊列里面嗎祝沸?
DelayQueue 要求元素必須實現(xiàn) Delayed 接口矮烹,也就是說 DelayQueue 的元素必須是 Delayed 的子類。而String類并沒有實現(xiàn) Delayed 接口罩锐,所以String 變量是不能放在 DelayQueue 隊列里奉狈。
6.如何查看 SynchronousQueue 隊列的大小涩惑?
實際上 SynchronousQueue 本身是沒有容量的仁期,所以也無法查看其容量的大小,其內(nèi)部的 size 方法都是寫死的返回 0
7.如果超出 LinkedBlockingQueue 的容量值,又會出現(xiàn)什么情況蟀拷?
如果有限定 LinkedBlockingQueue 的容量碰纬,當(dāng)達到容量值的時候put操作和offer操作加上超時時間會阻塞;如果沒有限定容量的話问芬,就可認為容量是無限大,直到耗盡機器的資源寿桨,發(fā)生OOM此衅。所以我們在使用 LinkedBlockingQueue 的時候最好能夠設(shè)置容量,防止耗盡內(nèi)容亭螟!