91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比

發布時間:2021-12-23 17:14:00 來源:億速云 閱讀:139 作者:柒染 欄目:大數據

這篇文章給大家介紹如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

今天學習LinkedBlockingQueue源碼并與之對比。

LinkedBlockingQueue總結

同樣先直接總結LinkedBlockingQueue相關的特性,再根據源碼來進行說明,它的主要特性如下:

1、他底層用鏈表實現數據存儲;

2、他是一個FIFO無界阻塞隊列。數據最大長度默認Intenger的最大值Integer.MAX_VALUE,也可以設置長度;

重要屬性介紹

主要屬性如下圖:

 如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比

LinkedBlockingQueue有一個內部類Node,用來組成它存儲數據的鏈表,Node的item數據用來存儲數據,next表示下一個節點,尾節點的next是null。

capacity容量表示隊列最多可存儲的數據量,初始化的時候設置,默認是Integer.MAX_VALUE;

count表示當前存儲數據的數量,它是AtomicInteger類型(可以想想為什么?);

head鏈表的頭節點,它的item不存放數據;

tail鏈表的尾節點,它的next為null,也就是沒有下一個節點;

takeLock與notEmpty控制take方法的阻塞;

putLock與notFull控制put方法的阻塞; 

從上面屬性可以猜出來LinkedBlockingQueue是用兩個鎖來控制數據的讀和寫,相當于把讀和寫分開,可以同時存在讀和寫操作,所以count有可能同時存在多個線程修改,有線程安全問題所以用AtomicInteger

最關鍵的兩個私有方法

同樣LinkedBlockingQueue也有兩個相同的關鍵方法,具體代碼和解釋如下圖:

 如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比

LinkedBlockingQueue的enqueue和dequeue方法比ArrayBlockingQueue的更加簡單;

enqueue方法就是把新的節點放到last的next,然后把節點設置成尾節點。

dequeue是先拿到頭節點next節點作為first節點,然后之前的頭節點就的next設置成了自己,就脫離了鏈表,下次GC就會被回收掉。

然后first就作為head,把item拿出來后設置為null,所以頭節點是不存儲數據的,并且是由下一個節點升級來的。 

LinkedBlockingQueue的這兩個方法比較簡單,但是也可以看出它實現了FIFO先進先出

主要方法介紹

LinkedBlockingQueue與ArrayBlockingQueue一樣都是繼承至 AbstractQueue并實現 BlockingQueue接口,所以他們提供的方法都差不多,功能也類似,主要實現不同,上一篇已經詳細講了,這里就只看一下take和put方法的實現。

put方法源碼如下圖:

 如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比

一共分四步:

把數據封裝成Node節點,獲取put鎖;

驗證隊列是否已滿,滿則阻塞線程;

如果沒有滿則把節點加到隊列中,count加1,并獲取加之前的數量;

如果現在數量還是小于最大容量則喚醒阻塞的put線程,如果之前數量是0則喚醒take線程; 

take方法源碼如下圖:

 如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比

take方法和put方法差不多,主要分以下四步:

首先獲取take鎖;

判斷隊列中是否有數據,如果沒有則阻塞線程;

調用dequeue方法獲取數據,并把count減1;

如果獲取前隊列數量大于1則說明還有數據,可以喚醒其他take線程,如果獲取前隊列數量等于最大容器數量則說明有可能有阻塞的put線程,需要喚醒; 

可以看到put和take方法很簡單,都是先獲取到對于的鎖,然后根據隊列數量判斷是否阻塞,然后再添加或者獲取數據,最后根據喚醒對應線程

與ArrayBlockingQueue對比(重點)

LinkedBlockingQueue與ArrayBlockingQueue是非常相似的類,通過對比能夠更體現他們的優缺點,主要對比如下:

從基礎屬性對比LinkedBlockingQueue底層實現是鏈表,ArrayBlockingQueue是數組。ArrayBlockingQueue初始化需要一個數組,而LinkedBlockingQueue是動態數量的Node對象;所以ArrayBlockingQueue需要預先分配內存,而LinkedBlockingQueue不用,如果預計需要緩存的數據很多的,那么ArrayBlockingQueue一開始就需要很大一塊數據

但是ArrayBlockingQueue添加元素更快,因為它只是要要保存的對象的引用放到數組對應位置,而LinkedBlockingQueue需要創建一個Node對象;同時在獲取后這個Node對象變成了垃圾,在讀寫很大的情況會多出很多垃圾,可能會影響程序的性能; 

ArrayBlockingQueue用一個鎖控制讀寫,LinkedBlockingQueue用兩個鎖分別控制讀寫。因為ArrayBlockingQueue為了避免數據被覆蓋,而LinkedBlockingQueue不用擔心這種情況,可以同時支持讀寫,而ArrayBlockingQueue同一時刻支持一個操作,所以LinkedBlockingQueue吞吐量更高。 

所以ArrayBlockingQueue會占用固定的內存,所以不能支持太大的緩存,但是每次操作延遲更加低,而LinkedBlockingQueue不用暫用一個初始化的內存,但是每次操作消耗的內存更大,不過同時支持讀寫所以吞吐量更高

但是在使用LinkedBlockingQueue時,如果使用默認大小且當生產速度大于消費速度時候,有可能會內存溢出。

LinkedBlockingQueue與ArrayBlockingQueue提供的功能完全相同,但是他們底層的實現不同,所以側重點不同,在使用中可以根據情況選擇。 

關于如何進行阻塞隊列LinkedBlockingQueue源碼學習與對比就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚宁县| 凌云县| 扬州市| 林甸县| 杂多县| 桦川县| 武功县| 山东省| 公安县| 调兵山市| 青浦区| 收藏| 宁都县| 孟村| 吕梁市| 新余市| 荃湾区| 霍林郭勒市| 富民县| 革吉县| 孝义市| 昔阳县| 苍南县| 长垣县| 宾阳县| 靖西县| 会同县| 罗山县| 佛山市| 浮山县| 称多县| 宜城市| 阿合奇县| 大方县| 茌平县| 垦利县| 南和县| 海南省| 顺平县| 田阳县| 宁南县|