并發(fā)編程ConcurrentLinkedQueue示例詳解
ConcurrentLinkedQueue
ConcurrentLinkedQueue是非阻塞線程安全的隊(duì)列,適用于高并發(fā)的場(chǎng)景。是一個(gè)基于鏈接節(jié)點(diǎn)的無界線程安全隊(duì)列,按照 FIFO(先進(jìn)先出)原則對(duì)元素進(jìn)行排序。隊(duì)列元素中不可以放置null元素(內(nèi)部實(shí)現(xiàn)的特殊節(jié)點(diǎn)除外)

ConcurrentLinkedQueue原理
- ConcurrentLinked是由鏈表結(jié)構(gòu)組成的線程安全的先進(jìn)先出無界隊(duì)列。
- 當(dāng)多線程要共享訪問集合時(shí),ConcurrentLinkedQueue是一個(gè)比較好的選擇。
- 不允許插入null元素
- 支持非阻塞地訪問并發(fā)安全的隊(duì)列,不會(huì)拋出ConcurrentModifiationException異常。
- size方法不是準(zhǔn)確的,因?yàn)樵诮y(tǒng)計(jì)集合的時(shí)候,隊(duì)列可能正在添加元素,導(dǎo)致統(tǒng)計(jì)不準(zhǔn)。
- 批量操作addAll、removeAll、retainAll、containsAll、equals和toArray不保證原子性(操作不可分割)
- 添加元素happen-before其他線程移除元素。
ConcurrentLinkedQueue類繼承AbstractQueue抽象類
具有隊(duì)列的功能;實(shí)現(xiàn)了Queue接口,可作為隊(duì)列使用。
- ConcurrentLinkedQueue繼承于AbstractQueue。
- ConcurrentLinkedQueue內(nèi)部是通過鏈表來實(shí)現(xiàn)的。同時(shí)包含鏈表的頭節(jié)點(diǎn)head和尾節(jié)點(diǎn)tail。
- ConcurrentLinkedQueue按照 FIFO(先進(jìn)先出)原則對(duì)元素進(jìn)行排序。元素都是從尾部插入到鏈表,從頭部開始返回。
- ConcurrentLinkedQueue的鏈表Node中的next的類型是volatile,而且鏈表數(shù)據(jù)item的類型也是volatile。ConcurrentLinkedQueue就是通過volatile來實(shí)現(xiàn)多線程對(duì)競爭資源的互斥訪問的。
- 其中head節(jié)點(diǎn)存放鏈表第一個(gè)item為null的節(jié)點(diǎn),tail則并不是總指向最后一個(gè)節(jié)點(diǎn)
ConcurrentLinkedQueue操作方法
private transient volatile Node<E> head;
private transient volatile Node<E> tail;
public ConcurrentLinkedQueue() {
head = tail = new Node<E>(null);
}
構(gòu)造函數(shù)中,新建了一個(gè)“內(nèi)容為null的節(jié)點(diǎn)”,并設(shè)置表頭head和表尾tail的值為新節(jié)點(diǎn)。 head和tail是volatile類型,具有volatile賦予的含義:“即對(duì)一個(gè)volatile變量的讀,總是能看到(任意線程)對(duì)這個(gè)volatile變量最后的寫入”。
private static class Node<E> {
volatile E item;
volatile Node<E> next;
Node(E item) {
UNSAFE.putObject(this, itemOffset, item);
}
}
Node是單向鏈表節(jié)點(diǎn),next指向下一個(gè)Node,item用于存儲(chǔ)數(shù)據(jù)。Node中操作節(jié)點(diǎn)數(shù)據(jù)的API,是通過Unsafe機(jī)制的CAS函數(shù)實(shí)現(xiàn)的;例如casNext()是通過CAS函數(shù)“比較并設(shè)置節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)”。
1、添加
以add(E e)為例對(duì)ConcurrentLinkedQueue中的添加
public boolean add(E e) {
return offer(e);
}
add()實(shí)際上是調(diào)用的offer()來完成添加操作的;offer(E e)的作用就是將元素e添加到鏈表的末尾。
2、刪除
poll():在鏈表頭部獲取并且移除一個(gè)元素
poll()的作用就是刪除鏈表的表頭節(jié)點(diǎn),并返回被刪節(jié)點(diǎn)對(duì)應(yīng)的值。
3、peek操作
peek操作是獲取鏈表頭部一個(gè)元素(只讀取不移除)。
以上就是并發(fā)編程ConcurrentLinkedQueue示例詳解的詳細(xì)內(nèi)容,更多關(guān)于并發(fā)編程ConcurrentLinkedQueue的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java模擬棧和隊(duì)列數(shù)據(jù)結(jié)構(gòu)的基本示例講解
這篇文章主要介紹了Java模擬棧和隊(duì)列數(shù)據(jù)結(jié)構(gòu)的基本示例,棧的后進(jìn)先出和隊(duì)列的先進(jìn)先出是數(shù)據(jù)結(jié)構(gòu)中最基礎(chǔ)的知識(shí),本文則又對(duì)Java實(shí)現(xiàn)棧和隊(duì)列結(jié)構(gòu)的方法進(jìn)行了細(xì)分,需要的朋友可以參考下2016-04-04
SpringBoot?基于?MongoTemplate?的工具類過程詳解
MongoDB是一個(gè)高性能,開源,無模式的文檔型數(shù)據(jù)庫,是當(dāng)前NoSql數(shù)據(jù)庫中比較熱門的一種,這篇文章主要介紹了SpringBoot基于MongoTemplate的工具類,需要的朋友可以參考下2023-09-09
java使用tess4j進(jìn)行圖片文字識(shí)別功能
Tess4J?是Java?(JNA)?對(duì)?Tesseract?OCR?API?的封裝,Tess4J是java直接可使用的jar包,而Tesseract?OCR是支持Tess4J進(jìn)文件文字識(shí)別的基礎(chǔ),Tess4J可直接使用Maven方式引入,這篇文章主要介紹了java使用tess4j進(jìn)行圖片文字識(shí)別,需要的朋友可以參考下2023-04-04
關(guān)于mybatis-plus邏輯刪除自動(dòng)填充更新時(shí)間的問題
mybatis-plus是對(duì)mybatis的增強(qiáng),mybatis-plus更像是面向?qū)ο缶幊?,?shù)據(jù)庫基本CRUD的操作可以不用手動(dòng)編寫SQL語句,大大提高了開發(fā)的效率,這篇文章主要介紹了mybatis-plus邏輯刪除自動(dòng)填充更新時(shí)間問題,需要的朋友可以參考下2022-07-07
SpringBoot?web靜態(tài)資源映射實(shí)現(xiàn)步驟詳解
在springBoot中的靜態(tài)資源的映射是通過SpringMVC中的resourceHttpRequestHandler來進(jìn)行實(shí)現(xiàn)的。在該請(qǐng)求映射器中默認(rèn)規(guī)定了,SpringBoot會(huì)將classPath或者ServletContext下的/static?(/public、/resources?或?/META-INF/resources)目錄中,存放靜態(tài)資源2022-09-09

