亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時(shí)間:2021年06月06日 15:52:39   作者:Java_maxiaoyi  
今天給大家?guī)?lái)的文章是Java并發(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)部通過(guò)鏈表、數(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()方法來(lái)包裝我們的 HashMap。但這是通過(guò)使用一個(gè)全局的鎖來(lái)同步不同線程間的并發(fā)訪問(wèn),因此會(huì)帶來(lái)不可忽視的性能問(wèn)題。

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

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í)訪問(wèn) List 的內(nèi)部數(shù)據(jù),畢竟讀取操作是安全的。

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

1.3.2 CopyOnWriteArrayList 是如何做到的?

Java并發(fā)容器講解

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

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

讀取操作沒(méi)有任何同步控制和鎖操作,理由就是內(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è)副本出來(lái)。

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)者”問(wèn)題中,其原因是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)來(lái)使用,而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)做無(wú)界隊(duì)列也可以當(dāng)做有界隊(duì)列來(lái)使用,同樣滿足 FIFO 的特性,與 ArrayBlockingQueue 相比起來(lái)具有更高的吞吐量,為了防止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ì)很低,跳表就不一樣了。跳表是一種可以用來(lái)快速查找的數(shù)據(jù)結(jié)構(gòu),有點(diǎn)類似于平衡樹(shù)。它們都可以對(duì)元素進(jìn)行快速地查找。但一個(gè)重要的區(qū)別是:對(duì)平衡樹(shù)的插入和刪除往往很可能導(dǎo)致 平衡樹(shù)進(jìn)行一次全局的調(diào)整。而對(duì)跳表的插入和刪除只需要對(duì)整個(gè)數(shù)據(jù)結(jié)構(gòu)的局部進(jìn)行操作即可。這樣 帶來(lái)的好處是:在高并發(fā)的情況下,你會(huì)需要一個(gè)全局鎖來(lái)保證整個(gè)平衡樹(shù)的線程安全。而對(duì)于跳表, 你只需要部分鎖即可。這樣,在高并發(fā)環(huán)境下,你就可以擁有更好的性能。而就查詢的性能而言,跳表的時(shí)間復(fù)雜度也是 O(logn) 所以在并發(fā)數(shù)據(jù)結(jié)構(gòu)中,JDK 使用跳表來(lái)實(shí)現(xiàn)一個(gè) Map。

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

Java并發(fā)容器講解

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

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

Java并發(fā)容器講解

查找 18 的時(shí)候原來(lái)需要遍歷 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基礎(chǔ)之代理原理與用法詳解

    Java基礎(chǔ)之代理原理與用法詳解

    這篇文章主要介紹了Java基礎(chǔ)之代理原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了java代理的概念、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • gradle安裝配置以及使用最新方法

    gradle安裝配置以及使用最新方法

    這篇文章主要給大家介紹了關(guān)于gradle安裝配置以及使用的相關(guān)資料,Gradle是一個(gè)基于ApacheAnt和ApacheMaven概念的項(xiàng)目自動(dòng)化構(gòu)建開(kāi)源工具,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • springboot項(xiàng)目中后端接收前端傳參的方法示例詳解

    springboot項(xiàng)目中后端接收前端傳參的方法示例詳解

    這篇文章主要介紹了springboot項(xiàng)目中一些后端接收前端傳參的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • 詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式

    詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式

    目前Java開(kāi)發(fā)包中包含了對(duì)動(dòng)態(tài)代理的支持,但是其實(shí)現(xiàn)只支持對(duì)接口的的實(shí)現(xiàn)。這篇文章主要介紹了詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式 ,有興趣的可以了解一下。
    2016-11-11
  • springboot如何統(tǒng)一設(shè)置時(shí)區(qū)

    springboot如何統(tǒng)一設(shè)置時(shí)區(qū)

    這篇文章主要介紹了springboot如何統(tǒng)一設(shè)置時(shí)區(qū)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Java利用序列化實(shí)現(xiàn)對(duì)象深度clone的方法

    Java利用序列化實(shí)現(xiàn)對(duì)象深度clone的方法

    這篇文章主要介紹了Java利用序列化實(shí)現(xiàn)對(duì)象深度clone的方法,實(shí)例分析了java序列化及對(duì)象克隆的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • java通過(guò)Jsoup爬取網(wǎng)頁(yè)過(guò)程詳解

    java通過(guò)Jsoup爬取網(wǎng)頁(yè)過(guò)程詳解

    這篇文章主要介紹了java通過(guò)Jsoup爬取網(wǎng)頁(yè)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • idea使用jclasslib插件查看字節(jié)碼

    idea使用jclasslib插件查看字節(jié)碼

    這篇文章主要為大家介紹了idea使用jclasslib插件查看字節(jié)碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 詳解Java無(wú)需解壓直接讀取Zip文件和文件內(nèi)容

    詳解Java無(wú)需解壓直接讀取Zip文件和文件內(nèi)容

    本篇文章主要介紹了詳解Java無(wú)需解壓直接讀取Zip文件和文件內(nèi)容,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • java中ZXing 生成、解析二維碼圖片的小示例

    java中ZXing 生成、解析二維碼圖片的小示例

    ZXing 是一個(gè)開(kāi)源 Java 類庫(kù)用于解析多種格式的 1D/2D 條形碼,這篇文章主要介紹了java中ZXing 生成、解析二維碼圖片的小示例 ,有興趣的可以了解一下。
    2017-01-01

最新評(píng)論