欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的ConcurrentLinkedQueue松散隊(duì)列解析

 更新時(shí)間:2023年12月27日 11:11:08   作者:蝸牛^^O^  
這篇文章主要介紹了Java中的ConcurrentLinkedQueue松散隊(duì)列解析,鏈表是松散的,鏈表節(jié)點(diǎn)并不都是有效的,允許存在無(wú)效節(jié)點(diǎn)val=null,但是只有最后一個(gè)節(jié)點(diǎn)才能next=null,需要的朋友可以參考下

一、為什么叫松散隊(duì)列?

唯一一個(gè)使用cas實(shí)現(xiàn)的線程安全并發(fā)效率高的集合。

鏈表是松散的,鏈表節(jié)點(diǎn)并不都是有效的,允許存在無(wú)效節(jié)點(diǎn)val=null,但是只有最后一個(gè)節(jié)點(diǎn)才能next=null 為什么線程安全需要把鏈表做成松散的。就是因?yàn)槿腙?duì)分為兩步,cas設(shè)置最后一個(gè)節(jié)點(diǎn)的next,和cas設(shè)置tail,兩個(gè)操作之間并無(wú)原子性,所以可能并發(fā)操作了多個(gè)cas設(shè)置next,才設(shè)置tail。tail滯后很多。 出隊(duì)的時(shí)候,也需要分為兩步,cas將值設(shè)置成null。cas移動(dòng)head。head也會(huì)滯后很多。所以會(huì)有很多節(jié)點(diǎn)已經(jīng)出隊(duì)為null,但是依然可以遍歷到。因此叫做松散隊(duì)列。

二、如何實(shí)現(xiàn)線程安全?

add入隊(duì)操作

tail節(jié)點(diǎn)并不是最后一個(gè)節(jié)點(diǎn)

1、從 tail 節(jié)點(diǎn)開(kāi)始遍歷到尾節(jié)點(diǎn),若定位到尾節(jié)點(diǎn)(p.next == null),則入隊(duì)。

2、遍歷過(guò)程中,如果遍歷到無(wú)效節(jié)點(diǎn)(p.next == p)說(shuō)明p已經(jīng)并發(fā)出隊(duì),需要重新從有效節(jié)點(diǎn)(tail 或 head)開(kāi)始遍歷。

3、遍歷過(guò)程中,時(shí)刻關(guān)注 tail 節(jié)點(diǎn)是否無(wú)效。若無(wú)效了需要重新從最新的 tail(如果tail失效,從head) 開(kāi)始遍歷,否則繼續(xù)遍歷當(dāng)前的下一個(gè)節(jié)點(diǎn)。

4、找到最后一個(gè)節(jié)點(diǎn)后,進(jìn)行入隊(duì)操作,使用cas將next修改為新節(jié)點(diǎn),如果tail->next!=null,需要使用cas將tail設(shè)置為新節(jié)點(diǎn)。

cas設(shè)置next,和cas設(shè)置tail,兩個(gè)操作之間并無(wú)原子性,所以可能并發(fā)操作了多個(gè)cas設(shè)置next,才設(shè)置tail。tail滯后很多。

如下圖B節(jié)點(diǎn)已經(jīng)被poll了,tail還在B節(jié)點(diǎn)前面。tail失效了,從tail無(wú)法遍歷到最后一個(gè)節(jié)點(diǎn)。

在這里插入圖片描述

poll出隊(duì)操作

1、從 head 節(jié)點(diǎn)開(kāi)始遍歷找出首個(gè)有效節(jié)點(diǎn)(p.item != null),返回該節(jié)點(diǎn)的數(shù)據(jù)(p.item)。

2、遍歷過(guò)程中,如果遍歷到尾節(jié)點(diǎn)(p.next == null),則返回空。

3、遍歷過(guò)程中,如果遍歷到無(wú)效節(jié)點(diǎn)(p.next == p),說(shuō)明其他線程修改了 head,需要重新從有效節(jié)點(diǎn)(新的 head)開(kāi)始遍歷。

4、cas將值設(shè)置成null。cas移動(dòng)head。

5、更新head,需要注意的是,并不是每次出隊(duì)時(shí)都執(zhí)行 updateHead() 更新 head 節(jié)點(diǎn): 當(dāng) head 節(jié)點(diǎn)里有元素時(shí),直接彈出 head 節(jié)點(diǎn)里的元素,設(shè)置為null,而不會(huì)更新 head 節(jié)點(diǎn)。

在這里插入圖片描述

只有當(dāng) head 節(jié)點(diǎn)里沒(méi)有元素時(shí),出隊(duì)操作才會(huì)更新 head 節(jié)點(diǎn)。

在這里插入圖片描述

三、優(yōu)缺點(diǎn)

從它的入隊(duì)出隊(duì)機(jī)制就可以看出,優(yōu)缺點(diǎn)非常明顯。

優(yōu)點(diǎn): 1、并發(fā)效率高,入隊(duì)出隊(duì)不需要加鎖進(jìn)行線程同步,全程使用cas操作

缺點(diǎn): 1、入隊(duì)出隊(duì)都分為兩步cas,cas之間是控制不了的,所以會(huì)產(chǎn)生tail滯后,tail失效,鏈表節(jié)點(diǎn)poll了,還可以繼續(xù)訪問(wèn)沒(méi)有釋放,內(nèi)存是松散的,無(wú)效節(jié)點(diǎn)占用內(nèi)存,內(nèi)存開(kāi)銷(xiāo)大。

2、由于head和tail都不是嚴(yán)格指向頭尾,每次poll,add都需要遍歷,浪費(fèi)時(shí)間效率。concurrentLinkedQueue存的元素越多,效率越低。因此只適合高并發(fā)小容量的場(chǎng)景使用。

3、size獲取大小也要遍歷所有節(jié)點(diǎn)才行

到此這篇關(guān)于Java中的ConcurrentLinkedQueue松散隊(duì)列解析的文章就介紹到這了,更多相關(guān)ConcurrentLinkedQueue松散隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的JetCache?實(shí)戰(zhàn)

    Java中的JetCache?實(shí)戰(zhàn)

    這篇文章主要介紹了Java中的JetCache實(shí)戰(zhàn),JetCache是一個(gè)基于Java的緩存系統(tǒng)封裝,提供統(tǒng)一的API和注解來(lái)簡(jiǎn)化緩存的使用,下文更多相關(guān)資料需要的小伙伴可以參考一下
    2022-04-04
  • Spring MVC創(chuàng)建項(xiàng)目踩過(guò)的bug

    Spring MVC創(chuàng)建項(xiàng)目踩過(guò)的bug

    這篇文章主要介紹了Spring MVC創(chuàng)建項(xiàng)目踩過(guò)的bug,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SpringAOP如何修改請(qǐng)求參數(shù)列表

    SpringAOP如何修改請(qǐng)求參數(shù)列表

    這篇文章主要介紹了SpringAOP如何修改請(qǐng)求參數(shù)列表問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • RabbitMQ 的消息持久化與 Spring AMQP 的實(shí)現(xiàn)詳解

    RabbitMQ 的消息持久化與 Spring AMQP 的實(shí)現(xiàn)詳解

    這篇文章主要介紹了RabbitMQ 的消息持久化與 Spring AMQP 的實(shí)現(xiàn)剖析詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • jsp+dao+bean+servlet(MVC模式)實(shí)現(xiàn)簡(jiǎn)單用戶(hù)登錄和注冊(cè)頁(yè)面

    jsp+dao+bean+servlet(MVC模式)實(shí)現(xiàn)簡(jiǎn)單用戶(hù)登錄和注冊(cè)頁(yè)面

    這篇文章主要介紹了jsp+dao+bean+servlet(MVC模式)實(shí)現(xiàn)簡(jiǎn)單用戶(hù)登錄和注冊(cè)頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明

    反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明

    這篇文章主要介紹了反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java 5個(gè)人坐在一起(有關(guān)第五個(gè)人歲數(shù)的問(wèn)題)

    Java 5個(gè)人坐在一起(有關(guān)第五個(gè)人歲數(shù)的問(wèn)題)

    利用遞歸的方法,遞歸分為回推和遞推兩個(gè)階段。要想知道第五個(gè)人歲數(shù),需知道第四人的歲數(shù),依次類(lèi)推,推到第一人(10歲),再往回推,需要的朋友可以參考下
    2017-02-02
  • ArrayList的自動(dòng)擴(kuò)充機(jī)制實(shí)例解析

    ArrayList的自動(dòng)擴(kuò)充機(jī)制實(shí)例解析

    本文主要介紹了ArrayList的自動(dòng)擴(kuò)充機(jī)制,由一個(gè)題目切入主題,逐步向大家展示了ArrayList的相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • IDEA使用JDBC安裝配置jar包連接MySQL數(shù)據(jù)庫(kù)

    IDEA使用JDBC安裝配置jar包連接MySQL數(shù)據(jù)庫(kù)

    這篇文章介紹了IDEA使用JDBC安裝配置jar包連接MySQL數(shù)據(jù)庫(kù)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • Java編程中的性能優(yōu)化如何實(shí)現(xiàn)

    Java編程中的性能優(yōu)化如何實(shí)現(xiàn)

    這篇文章主要介紹了Java編程中的性能優(yōu)化如何實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10

最新評(píng)論