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

JAVA 并發(fā)容器的一些易出錯點你知道嗎

 更新時間:2021年09月02日 11:00:50   作者:冰 河  
今天給大家?guī)淼奈恼率荍ava并發(fā)編程的相關(guān)知識,文中對java同步容器與并發(fā)容器做了非常詳細的介紹及代碼示例,需要的朋友可以參考下

并發(fā)容器

與同步容器一樣,并發(fā)容器在總體上也可以分為四大類,分別為:List、Set、Map和Queue??傮w上如下圖所示。

在這里插入圖片描述

接下來,我們分別介紹下這些并發(fā)容器在使用時的注意事項和避免踩到的坑。

List

并發(fā)容器中的List相對來說比較簡單,就一個CopyOnWriteArrayList。大家可以從字面的意思中就能夠體會到:CopyOnWrite,在寫的時候進行復(fù)制操作,也就是說在進行寫操作時,會將共享變量復(fù)制一份。那這樣做有什么好處呢?最大的好處就是:讀操作可以做到完全無鎖化。

在CopyOnWriteArrayList內(nèi)部維護了一個數(shù)組,成員變量array指向這個數(shù)組,其核心源代碼如下所示。

private transient volatile Object[] array;
final Object[] getArray() {
	return array;
}
final void setArray(Object[] a) {
	array = a;
}

當進行操作時,都是基于array指向的這個內(nèi)部數(shù)組進行的。例如,我們使用Iterator迭代器遍歷這個數(shù)組時,會按照下圖所示的方式進行讀操作。

在這里插入圖片描述

如果在遍歷CopyOnWriteArrayList時發(fā)生寫操作,例如,向數(shù)組中增加一個元素時,CopyOnWriteArrayList則會將內(nèi)部的數(shù)組復(fù)制一份出來,然后會在新復(fù)制出來的數(shù)組上添加新的元素,添加完再將array指向新的數(shù)組,如下圖所示。

在這里插入圖片描述

對于CopyOnWriteArrayList的其他寫操作和添加元素的操作原理相同,這里就不再贅述了。

使用CopyOnWriteArrayList時需要注意的是:

CopyOnWriteArrayList只適合寫操作比較少的場景,并且能夠容忍讀寫操作在短時間內(nèi)的不一致。CopyOnWriteArrayList的迭代器是只讀的,不支持寫操作。

Set

對于Set接口來說,并發(fā)容器中主要有兩個實現(xiàn)類,一個是CopyOnWriteArraySet,另一個是ConcurrentSkipListSet。其中,

CopyOnWriteArraySet的使用場景、原理與注意事項和CopyOnWriteArrayList一致。而ConcurrentSkipListSet的使用場景、原理和注意事項和下文的ConcurrentSkipListMap一致。這里,我就不再贅述啦。

Map

在并發(fā)容器中,Map接口的實現(xiàn)類主要有ConcurrentHashMap和ConcurrentSkipListMap,而ConcurrentHashMap和ConcurrentSkipListMap最大的區(qū)別就是:ConcurrentHashMap的Key是無序的,而ConcurrentSkipListMap的Key是有序的。

在使用ConcurrentHashMap和ConcurrentSkipListMap時,需要注意的是:ConcurrentHashMap和ConcurrentSkipListMap的Key和Value都不能為空。

這里,我們可以將Map相關(guān)的類總結(jié)成一個表格,如下所示。

Map的實現(xiàn)類Key是否可為空Value是否可為空是否是線程安全的
HashMap
TreeMap
HashTable
ConcurrentHashMap
ConcurrentSkipListMap

這樣,大家記憶起來就方便多了。

這里,ConcurrentSkipListMap是基于“跳表”實現(xiàn)的,跳表的插入、刪除、查詢的平均時間復(fù)雜度為O(log n),這些時間復(fù)雜度在理論上與線程數(shù)沒有關(guān)系。如果要追求性能的話,可以嘗試使用ConcurrentSkipListMap。

Queue

在Java的并發(fā)容器中,Queue相對來說比較復(fù)雜。我們先來了解幾個概念:

  • 阻塞隊列:阻塞一般就是指當隊列已滿時,入隊操作會阻塞;當隊列為空時,出隊操作就會阻塞。
  • 非阻塞隊列:隊列的入隊和出隊操作不會阻塞。
  • 單端隊列:隊列的入隊操作只能在隊尾進行,隊列的出隊操作只能在隊首進行。
  • 雙端隊列:隊列的入隊操作和出隊操作都可以在隊首和隊尾進行。

我們可以將上述的隊列進行組合,將隊列分為單端阻塞隊列、雙端阻塞隊列、單端非阻塞隊列和雙端非阻塞隊列。

在這里插入圖片描述

在Java的并發(fā)容器中,會使用明顯的標識來區(qū)分不同類型的隊列。

  • 阻塞隊列一個明顯的標識就是使用Blocking修飾,例如,ArrayBlockingQueue和LinkedBlockingQueue都是阻塞隊列。
  • 單端隊列會使用Queue標識,例如ArrayBlockingQueue和LinkedBlockingQueue也是單端隊列。
  • 雙端隊列會使用Deque標識,例如LinkedBlockingDeque和ConcurrentLinkedDeque都是雙端隊列。

接下來,我們就分別簡單聊聊這四種類型的隊列。

單端阻塞隊列

在Java的并發(fā)容器中,單端阻塞隊列的主要實現(xiàn)是BlockingQueue,主要包括:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、LinkedTransferQueue、PriorityBlockingQueue和DelayQueue。

在這里插入圖片描述

單端阻塞隊列的內(nèi)部一般會有一個隊列。

在實現(xiàn)上,內(nèi)部的隊列可以是數(shù)組,例如ArrayBlockingQueue,也可以是鏈表,例如LinkedBlockingQueue。

也可以在內(nèi)部不存在隊列,例如SynchronousQueue,SynchronousQueue實現(xiàn)了生產(chǎn)者的入隊操作必須等待消費者的出隊操作完成之后才能進行。

LinkedTransferQueue集成了LinkedBlockingQueue和SynchronousQueue的優(yōu)點,并且性能比LinkedBlockingQueue好。

PriorityBlockingQueue實現(xiàn)了按照優(yōu)先級進行出隊操作,也就是說,隊列元素在PriorityBlockingQueue內(nèi)部可以按照某種規(guī)則進行排序。

DelayQueue是延時隊列,實現(xiàn)了在一段時間后再出隊的操作。

雙端阻塞隊列

雙端阻塞隊列的實現(xiàn)主要是LinkedBlockingDeque。示意圖如下所示。

在這里插入圖片描述

單端非阻塞隊列

單端非阻塞隊列的實現(xiàn)主要是ConcurrentLinkedQueue,示意圖如下所示。

在這里插入圖片描述

雙端非阻塞隊列

雙端非阻塞隊列的實現(xiàn)主要是ConcurrentLinkedDeque,示意圖如下所示。

在這里插入圖片描述

有界與無界隊列

使用隊列時,還要注意隊列的有界與無界問題,也就是在使用隊列時,需要注意隊列是否有容量限制。

在實際工作中,一般推薦使用有界隊列。因為無界隊列很容易導(dǎo)致內(nèi)存溢出的問題。在Java的并發(fā)容器中,只有ArrayBlockingQueue和LinkedBlockingQueue支持有界,其他的隊列都是無界隊列。

在使用時,一定要注意內(nèi)存溢出問題。

總結(jié)

今天我們主要介紹了JDK1.5之后提供的并發(fā)容器,主要包括:List、Set、Map和Queue,而Queue又可以分為:單端阻塞隊列、雙端阻塞隊列、單端非阻塞隊列和雙端非阻塞隊列。對于每種并發(fā)容器,我們簡單介紹了其基本原理和注意事項。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Java如何使用Agent和ASM在字節(jié)碼層面實現(xiàn)方法攔截

    Java如何使用Agent和ASM在字節(jié)碼層面實現(xiàn)方法攔截

    Agent是一種運行在 Java 虛擬機 (JVM) 上的特殊程序,ASM是一個輕量級的 Java 字節(jié)碼編輯和分析框架,本文為大家介紹了如何利用他們在字節(jié)碼層面實現(xiàn)方法攔截,感興趣的可以了解一下
    2023-05-05
  • java springboot郵箱找回密碼功能的實現(xiàn)講解

    java springboot郵箱找回密碼功能的實現(xiàn)講解

    這篇文章主要介紹了java springboot郵箱找回密碼功能的實現(xiàn)講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Spring cloud Gateway簡介及相關(guān)配置方法

    Spring cloud Gateway簡介及相關(guān)配置方法

    這篇文章主要介紹了Spring cloud Gateway簡介及相關(guān)配置方法,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • springboot通過注解、接口創(chuàng)建定時任務(wù)詳解

    springboot通過注解、接口創(chuàng)建定時任務(wù)詳解

    使用SpringBoot創(chuàng)建定時任務(wù)其實是挺簡單的,這篇文章主要給大家介紹了關(guān)于springboot如何通過注解、接口創(chuàng)建這兩種方法實現(xiàn)定時任務(wù)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • springcloud本地服務(wù)不注冊到注冊中心的解決方案

    springcloud本地服務(wù)不注冊到注冊中心的解決方案

    這篇文章主要介紹了springcloud本地服務(wù)不注冊到注冊中心,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Spring Cloud實戰(zhàn)技巧之使用隨機端口

    Spring Cloud實戰(zhàn)技巧之使用隨機端口

    這篇文章主要給大家介紹了關(guān)于Spring Cloud實戰(zhàn)技巧之使用隨機端口的相關(guān)資料,文中介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面跟著小編一起來學(xué)習學(xué)習吧。
    2017-06-06
  • MybatisPlus開啟二級緩存的方法詳解

    MybatisPlus開啟二級緩存的方法詳解

    這篇文章主要介紹了MybatisPlus開啟二級緩存的方法詳解,二級緩存是基于mapper文件的namespace級別,也就是說多個sqlSession可以共享一個mapper中的二級緩存區(qū)域,需要的朋友可以參考下
    2023-11-11
  • jstorm源碼解析之bolt異常處理方法

    jstorm源碼解析之bolt異常處理方法

    下面小編就為大家?guī)硪黄猨storm源碼解析之bolt異常處理方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • java實現(xiàn)兩臺服務(wù)器間文件復(fù)制的方法

    java實現(xiàn)兩臺服務(wù)器間文件復(fù)制的方法

    這篇文章主要介紹了java實現(xiàn)兩臺服務(wù)器間文件復(fù)制的方法,是對單臺服務(wù)器上文件復(fù)制功能的升級與改進,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • OpenCV實現(xiàn)普通閾值

    OpenCV實現(xiàn)普通閾值

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)普通閾值,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論

民乐县| 招远市| 新竹县| 连江县| 安阳市| 金山区| 和平区| 临颍县| 江城| 沐川县| 保康县| 长武县| 金华市| 绥江县| 平遥县| 永康市| 浙江省| 常宁市| 凌海市| 渑池县| 会同县| 若尔盖县| 环江| 平潭县| 福州市| 龙口市| 曲阳县| 花莲市| 青铜峡市| 双城市| 裕民县| 商洛市| 南川市| 福清市| 特克斯县| 通辽市| 双柏县| 惠安县| 沧源| 茂名市| 深州市|