最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)容器相關(guān)知識(shí)總結(jié)

 更新時(shí)間:2021年06月06日 15:52:39   作者:Java_maxiaoyi  
今天給大家?guī)淼奈恼率荍ava并發(fā)容器的相關(guān)知識(shí),文中有非常詳細(xì)的介紹,對(duì)正在學(xué)習(xí)Java并發(fā)容器的小伙伴們很有幫助,需要的朋友可以參考下

一、并發(fā)容器

1.1 JDK 提供的并發(fā)容器總結(jié)

JDK 提供的這些容器大部分在java.util.concurrent包中。

ConcurrentHashMap: 線程安全的 HashMap

CopyOnWriteArrayList: 線程安全的 List,在讀多寫少的場(chǎng)合性能非常好,遠(yuǎn)遠(yuǎn)好于 Vector.

ConcurrentLinkedQueue: 高效的并發(fā)隊(duì)列,使用鏈表實(shí)現(xiàn)??梢钥醋鲆粋€(gè)線程安全的

LinkedList,這是一個(gè)非阻塞隊(duì)列。

BlockingQueue: 這是一個(gè)接口,JDK 內(nèi)部通過鏈表、數(shù)組等方式實(shí)現(xiàn)了這個(gè)接口。表示阻塞隊(duì)列,非常適合用于作為數(shù)據(jù)共享的通道。

ConcurrentSkipListMap: 跳表的實(shí)現(xiàn)。這是一個(gè) Map,使用跳表的數(shù)據(jù)結(jié)構(gòu)進(jìn)行快速查找。

1.2 ConcurrentHashMap

我們知道 HashMap 不是線程安全的,在并發(fā)場(chǎng)景下如果要保證一種可行的方式是使用
Collections.synchronizedMap()方法來包裝我們的 HashMap。但這是通過使用一個(gè)全局的鎖來同步不同線程間的并發(fā)訪問,因此會(huì)帶來不可忽視的性能問題。

所以就有了 HashMap 的線程安全版本—— ConcurrentHashMap 的誕生。在 ConcurrentHashMap 中,無論是讀操作還是寫操作都能保證很高的性能:在進(jìn)行讀操作時(shí)(幾乎)不需要加鎖,而在寫操作時(shí) 通過鎖分段技術(shù)只對(duì)所操作的段加鎖而不影響客戶端對(duì)其它段的訪問。

1.3 CopyOnWriteArrayList

1.3.1 CopyOnWriteArrayList 簡(jiǎn)介

Java并發(fā)容器講解

在很多應(yīng)用場(chǎng)景中,讀操作可能會(huì)遠(yuǎn)遠(yuǎn)大于寫操作。由于讀操作根本不會(huì)修改原有的數(shù)據(jù),因此對(duì)于每 次讀取都進(jìn)行加鎖其實(shí)是一種資源浪費(fèi)。我們應(yīng)該允許多個(gè)線程同時(shí)訪問 List 的內(nèi)部數(shù)據(jù),畢竟讀取操作是安全的。

這和我們之前在多線程章節(jié)講過 ReentrantReadWriteLock 讀寫鎖的思想非常類似,也就是讀讀共享、寫寫互斥、讀寫互斥、寫讀互斥。JDK 中提供了 CopyOnWriteArrayList 類比相比于在讀寫鎖的思想又更進(jìn)一步。為了將讀取的性能發(fā)揮到極致, CopyOnWriteArrayList 讀取是完全不用加鎖的, 并且更厲害的是:寫入也不會(huì)阻塞讀取操作。只有寫入和寫入之間需要進(jìn)行同步等待。這樣一來,讀操 作的性能就會(huì)大幅度提升。那它是怎么做的呢?

1.3.2 CopyOnWriteArrayList 是如何做到的?

Java并發(fā)容器講解

1.3.3 CopyOnWriteArrayList 讀取和寫入源碼簡(jiǎn)單分析

1.3.3.1 CopyOnWriteArrayList 讀取操作的實(shí)現(xiàn)

讀取操作沒有任何同步控制和鎖操作,理由就是內(nèi)部數(shù)組 array 不會(huì)發(fā)生修改,只會(huì)被另外一個(gè) array替換,因此可以保證數(shù)據(jù)安全。

Java并發(fā)容器講解

1.3.3.2 CopyOnWriteArrayList 寫入操作的實(shí)現(xiàn)

CopyOnWriteArrayList 寫入操作 add() 方法在添加集合的時(shí)候加了鎖,保證了同步,避免了多線程寫的時(shí)候會(huì) copy 出多個(gè)副本出來。

Java并發(fā)容器講解

1.4 ConcurrentLinkedQueue

Java并發(fā)容器講解

1.5 BlockingQueue

1.5.1 BlockingQueue 簡(jiǎn)單介紹

上面我們己經(jīng)提到了 ConcurrentLinkedQueue 作為高性能的非阻塞隊(duì)列。下面我們要講到的是阻塞隊(duì)列——BlockingQueue。阻塞隊(duì)列(BlockingQueue)被廣泛使用在“生產(chǎn)者-消費(fèi)者”問題中,其原因是BlockingQueue 提供了可阻塞的插入和移除的方法。當(dāng)隊(duì)列容器已滿,生產(chǎn)者線程會(huì)被阻塞,直到隊(duì)列未滿;當(dāng)隊(duì)列容器為空時(shí),消費(fèi)者線程會(huì)被阻塞,直至隊(duì)列非空時(shí)為止。

BlockingQueue 是一個(gè)接口,繼承自 Queue,所以其實(shí)現(xiàn)類也可以作為 Queue 的實(shí)現(xiàn)來使用,而Queue 又繼承自 Collection 接口。下面是 BlockingQueue 的相關(guān)實(shí)現(xiàn)類:

Java并發(fā)容器講解

下面主要介紹一下:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,這三個(gè) BlockingQueue 的實(shí)現(xiàn)類。

1.5.2 ArrayBlockingQueue

Java并發(fā)容器講解

 Java并發(fā)容器講解

1.5.3 LinkedBlockingQueue

LinkedBlockingQueue 底層基于單向鏈表實(shí)現(xiàn)的阻塞隊(duì)列,可以當(dāng)做無界隊(duì)列也可以當(dāng)做有界隊(duì)列來使用,同樣滿足 FIFO 的特性,與 ArrayBlockingQueue 相比起來具有更高的吞吐量,為了防止LinkedBlockingQueue 容量迅速增,損耗大量?jī)?nèi)存。通常在創(chuàng)建 LinkedBlockingQueue 對(duì)象時(shí),會(huì)指定其大小,如果未指定,容量等于 Integer.MAX_VALUE。

相關(guān)構(gòu)造方法:

Java并發(fā)容器講解

1.5.4 PriorityBlockingQueue

Java并發(fā)容器講解

1.6 ConcurrentSkipListMap

為了引出 ConcurrentSkipListMap,先帶著大家簡(jiǎn)單理解一下跳表。

對(duì)于一個(gè)單鏈表,即使鏈表是有序的,如果我們想要在其中查找某個(gè)數(shù)據(jù),也只能從頭到尾遍歷鏈表, 這樣效率自然就會(huì)很低,跳表就不一樣了。跳表是一種可以用來快速查找的數(shù)據(jù)結(jié)構(gòu),有點(diǎn)類似于平衡樹。它們都可以對(duì)元素進(jìn)行快速地查找。但一個(gè)重要的區(qū)別是:對(duì)平衡樹的插入和刪除往往很可能導(dǎo)致 平衡樹進(jìn)行一次全局的調(diào)整。而對(duì)跳表的插入和刪除只需要對(duì)整個(gè)數(shù)據(jù)結(jié)構(gòu)的局部進(jìn)行操作即可。這樣 帶來的好處是:在高并發(fā)的情況下,你會(huì)需要一個(gè)全局鎖來保證整個(gè)平衡樹的線程安全。而對(duì)于跳表, 你只需要部分鎖即可。這樣,在高并發(fā)環(huán)境下,你就可以擁有更好的性能。而就查詢的性能而言,跳表的時(shí)間復(fù)雜度也是 O(logn) 所以在并發(fā)數(shù)據(jù)結(jié)構(gòu)中,JDK 使用跳表來實(shí)現(xiàn)一個(gè) Map。

跳表的本質(zhì)是同時(shí)維護(hù)了多個(gè)鏈表,并且鏈表是分層的

Java并發(fā)容器講解

最低層的鏈表維護(hù)了跳表內(nèi)所有的元素,每上面一層鏈表都是下面一層的子集。

跳表內(nèi)的所有鏈表的元素都是排序的。查找時(shí),可以從頂級(jí)鏈表開始找。一旦發(fā)現(xiàn)被查找的元素大于當(dāng)前鏈表中的取值,就會(huì)轉(zhuǎn)入下一層鏈表繼續(xù)找。這也就是說在查找過程中,搜索是跳躍式的。如上圖所示,在跳表中查找元素 18。

Java并發(fā)容器講解

查找 18 的時(shí)候原來需要遍歷 18 次,現(xiàn)在只需要 7 次即可。針對(duì)鏈表長(zhǎng)度比較大的時(shí)候,構(gòu)建索引查找效率的提升就會(huì)非常明顯。

從上面很容易看出,跳表是一種利用空間換時(shí)間的算法。

使用跳表實(shí)現(xiàn) Map 和使用哈希算法實(shí)現(xiàn) Map 的另外一個(gè)不同之處是:哈希并不會(huì)保存元素的順序,而跳表內(nèi)所有的元素都是排序的。因此在對(duì)跳表進(jìn)行遍歷時(shí),你會(huì)得到一個(gè)有序的結(jié)果。所以,如果你的應(yīng)用需要有序性,那么跳表就是你不二的選擇。JDK 中實(shí)現(xiàn)這一數(shù)據(jù)結(jié)構(gòu)的類是ConcurrentSkipListMap。

到此這篇關(guān)于Java并發(fā)容器相關(guān)知識(shí)總結(jié)的文章就介紹到這了,更多相關(guān)Java并發(fā)容器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA各種OOM代碼示例與解決方法

    JAVA各種OOM代碼示例與解決方法

    這篇文章主要給大家介紹了關(guān)于JAVA各種OOM代碼示例與解決方法的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java 將Word轉(zhuǎn)為HTML的方法

    Java 將Word轉(zhuǎn)為HTML的方法

    本文介紹如何在JAVA程序中將Word文檔通過Document.saveToFile()方法轉(zhuǎn)換為HTML文檔,導(dǎo)入jar的兩種方法,文中給大家詳細(xì)介紹,感興趣的朋友一起看看吧
    2021-10-10
  • Spring Boot部署到Tomcat過程中遇到的問題匯總

    Spring Boot部署到Tomcat過程中遇到的問題匯總

    這篇文章主要給大家分享了關(guān)于Spring Boot部署到Tomcat過程中遇到的一些問題,文中將解決的方法介紹非常詳細(xì),對(duì)同樣遇到這個(gè)問題的朋友具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Java 內(nèi)省introspector相關(guān)原理代碼解析

    Java 內(nèi)省introspector相關(guān)原理代碼解析

    這篇文章主要介紹了Java 內(nèi)省introspector相關(guān)原理代碼解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java多線程環(huán)境下使用的集合類示例詳解

    Java多線程環(huán)境下使用的集合類示例詳解

    這篇文章主要給大家介紹了關(guān)于Java多線程環(huán)境下使用的集合類的相關(guān)資料,開發(fā)過程中經(jīng)常遇到這種需求,文中通過代碼示例和圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Java中hashMap遍歷的9種方式

    Java中hashMap遍歷的9種方式

    hashMap是非常重要的容器類,本文主要介紹了Java中hashMap遍歷的9種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Java/Spring項(xiàng)目的包開頭為什么是com詳解

    Java/Spring項(xiàng)目的包開頭為什么是com詳解

    這篇文章主要介紹了Java/Spring項(xiàng)目的包開頭為什么是com的相關(guān)資料,在Java中包命名遵循域名反轉(zhuǎn)規(guī)則,即使用公司的域名反轉(zhuǎn)作為包的前綴,以確保其全球唯一性和避免命名沖突,這種規(guī)則有助于邏輯分層、代碼可讀性提升和標(biāo)識(shí)代碼來源,需要的朋友可以參考下
    2024-10-10
  • SpringBoot應(yīng)用部署之WAR包部署方式

    SpringBoot應(yīng)用部署之WAR包部署方式

    這篇文章主要介紹了SpringBoot應(yīng)用部署之WAR包部署方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Java中比較抽象類與接口的異同

    Java中比較抽象類與接口的異同

    大家好,本篇文章主要講的是Java中比較抽象類與接口的異同,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • SpringBoot3中Spring?WebFlux?SSE服務(wù)器發(fā)送事件的實(shí)現(xiàn)步驟

    SpringBoot3中Spring?WebFlux?SSE服務(wù)器發(fā)送事件的實(shí)現(xiàn)步驟

    本文介紹了如何使用SpringBoot3和響應(yīng)式編程實(shí)現(xiàn)服務(wù)器發(fā)送事件(SSE),并討論了其在實(shí)時(shí)數(shù)據(jù)推送場(chǎng)景中的優(yōu)勢(shì),通過示例代碼,展示了如何創(chuàng)建SSE控制器、客戶端接收數(shù)據(jù)以及優(yōu)化與擴(kuò)展,感興趣的朋友跟隨小編一起看看吧
    2024-11-11

最新評(píng)論

金溪县| 固阳县| 诏安县| 信丰县| 南召县| 海伦市| 门源| 包头市| 巴林右旗| 莎车县| 永兴县| 黎城县| 新疆| 定边县| 弥渡县| 固阳县| 阿克陶县| 大石桥市| 连云港市| 夏河县| 乡宁县| 黄大仙区| 施秉县| 始兴县| 安仁县| 临武县| 乐昌市| 靖安县| 龙山县| 临沧市| 托里县| 龙陵县| 常德市| 类乌齐县| 恩平市| 龙胜| 邵阳市| 巴林右旗| 新巴尔虎右旗| 阜宁县| 桐城市|