Java 并發---ConcurrentHashMap

concurrent包下的并發容器

JDK5中添加了新的concurrent包,相對同步容器而言,并發容器通過一些機制改進了并發性能。因為同步容器將所有對容器狀態的訪問都串行化了,這樣保證了線程的安全性,所以這種方法的代價就是嚴重降低了并發性,當多個線程競爭容器時,吞吐量嚴重降低。因此Java5開始針對多線程并發訪問設計,提供了并發性能較好的并發容器,引入了java.util.concurrent包。

與Vector、HashTable、Collections.synchronizedXxx()等同步容器相比,util.concurrent中引入的并發容器主要解決了兩個問題:

  1. 根據具體場景進行設計,盡量避免synchronized,提供并發性。
  2. 定義了一些并發安全的復合操作,并且保證并發環境下的迭代操作不會出錯。

util.concurrent中容器在迭代時,可以不封裝在synchronized中,可以保證不拋異常,但是未必每次看到的都是"最新的、當前的"數據。

下面是對并發容器的簡單介紹:

ConcurrentHashMap代替同步的Map(Collections.synchronized(new HashMap())),眾所周知,HashMap是根據散列值分段存儲的,同步Map在同步的時候鎖住了所有的段,而ConcurrentHashMap加鎖的時候根據散列值鎖住了散列值鎖對應的那段,因此提高了并發性能。ConcurrentHashMap也增加了對常用復合操作的支持,比如"若沒有則添加":putIfAbsent(),替換:replace()。這2個操作都是原子操作。

CopyOnWriteArrayList和CopyOnWriteArraySet分別代替List和Set,主要是在遍歷操作為主的情況下來代替同步的List和同步的Set,這也就是上面所述的思路:迭代過程要保證不出錯,除了加鎖,另外一種方法就是"克隆"容器對象。

ConcurrentLinkedQueue是一個先進先出的隊列。它是非阻塞隊列。

ConcurrentSkipListMap可以在高效并發中替代SortedMap(例如用Collections.synchronizedMap包裝的TreeMap)。

ConcurrentSkipListSet可以在高效并發中替代SortedSet(例如用Collections.synchronizedSet包裝的TreeMap)。

為什么使用ConcurrentHashMap

線程不安全的HashMap

并發編程中使用HashMap可能導致程序死循環,導致cpu利用率接近100%。具體原因是,再執行put操作時會引起死循環,多線程會導致HashMap的Entry鏈表形成環形數據結構,這樣的話Entry的next節點永遠不為空,就會產生死循環獲取Entry。

效率低下的HashTable

HashTable使用synchronized來保證線程安全,競爭激烈情況下,當一個線程訪問同步方法,其他線程也訪問同步方法,會進入阻塞或輪詢狀態。線程1使用put進行元素添加,線程2不但不能使用put方法,也不能使用get方法。

ConcurrentHashMap使用鎖分段技術

ConcurrentHashMap將數據分成一段一段地存儲,然后給每一段數據配一把鎖,并且其內部的結構可以讓其在進行寫操作的時候能夠將鎖的粒度保持盡量的小,不用對整個ConcurrentHashMap加鎖。當一個線程占用鎖訪問其中一個段數據的時候,其他段地數據也能被其他線程訪問。

ConcurrentHashMap的結構

ConcurrentHashMap是由Segment數組結構和HashEntry數組結構組成。Segment是一種可重入鎖ReentrantLock,在ConcurrentHashMap里扮演鎖的角色,HashEntry則用于存儲鍵值對數據。一個ConcurrentHashMap里包含一個Segment數組,Segment的結構和HashMap類似,是一種數組和鏈表結構, 一個Segment里包含一個HashEntry數組,每個HashEntry是一個鏈表結構的元素, 每個Segment守護著一個HashEntry數組里的元素,當對HashEntry數組的數據進行修改時,必須首先獲得它對應的Segment鎖。
ConcurrentHashMap結構圖

ConcurrentHashMap和HashTable的區別圖
ConcurrentHashMap和HashTable的區別圖

從上面的結構我們可以了解到,ConcurrentHashMap定位一個元素的過程需要進行兩次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的鏈表的頭部,因此,這一種結構的帶來的副作用是Hash的過程要比普通的HashMap要長,但是帶來的好處是寫操作的時候可以只對元素所在的Segment進行加鎖即可,不會影響到其他的Segment,這樣,在最理想的情況下,ConcurrentHashMap可以最高同時支持Segment數量大小的寫操作(剛好這些寫操作都非常平均地分布在所有的Segment上),所以,通過這一種結構,ConcurrentHashMap的并發能力可以大大的提高。

轉載于:https://www.cnblogs.com/hesier/p/5929626.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/256275.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/256275.shtml
英文地址,請注明出處:http://en.pswp.cn/news/256275.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【圖像處理】——圖像濾波(Python+opencv實現三種方法:均值濾波、中值濾波、高斯濾波等)

目錄 一、什么是濾波以及濾波的目的? 二、均值濾波(cv2.blur()) 1、原理 2、關鍵代碼

UIScrollView事件攔截

在日常的開發中,我們經常會用到UIScrollView,然而,它是一個問題頻出的控件,比如在nib中使用它就必須手動為它創建一個ContentView.當然了使用春代碼的時候使用了懶加載機制使得它能夠擁有一個contentView,今天我們不談這個問題,我們來談談UIScrollView的事件攔截相關的知識. 在…

Windows10下安裝QT5.14.2并用VS2019打開

安裝 從官網下載:QT 安裝方法僅需要注意: 1.最好不要安裝在C盤。 2.根據開發需要安裝功能模塊,具體見參考文章。 https://jingyan.baidu.com/article/656db918d9292ae380249c4f.html 因為是用于PCL編程的,所以只選了msvc2017_64,…

【圖像處理】——圖像質量評價指標信噪比(PSNR)和結構相似性(SSIM)(含原理和Python代碼)

目錄 一、信噪比(PSNR) 1、信噪比的原理與計算公式 2、Python常規代碼實現PSNR計算 3、TensorFlo

Error和Exception的區別

Error:值得是指與虛擬機相關的問題,比如虛擬機崩潰,虛擬機錯誤,內存空間不足,方法調用棧溢出。 對于這類錯誤應建議中斷。 Exception:是指程序員可以處理的異常,可以捕獲并且能夠恢復&#xf…

JAVA TCP/IP網絡通訊編程(二)

一個實例通過client端和server端通訊 客戶端通過TCP/IP傳輸資源文件,比如圖片,文字,音頻,視頻等..... 服務端接受到文件存入本地磁盤,返回接受到:“收到來自于"s.getInetAddress().getHostName()"…

C#中json序列化與反序列化

json格式概念 JSON(JavaScript Object Notation) 是一種輕量級的數據傳輸格式,其采用完全獨立于語言的文本格式,使JSON成為理想的數據交換語言。 json由兩種格式組成。 1.名稱/值”對的集合,可以一起創建多個"名稱 / 值對"。 { “…

volley用法之 以post方式發送 json 參數

需求是這樣 我們需要發送一個post請求向服務器要參數。要求是發送的post參數也要是json格式。 簡單一點的是這樣的: 如果要發送的是這樣簡單的json格式,我們可以簡單的使用map來實現: RequestQueue requestQueue Volley.newRequestQueue(get…

我的友情鏈接

小小忍者Tab轉載于:https://blog.51cto.com/12737170/2043087

JAVA 文件編譯執行與虛擬機(JVM)簡單介紹

詳見:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的內存分配 JAVA 文件編譯執行與虛擬機(JVM)介紹 Java 虛擬機(JVM)是可運行Java代碼的假想計算機。只要根據JVM規格描述將解釋器移植到特定的計算機上,就能保證經過編譯的任…

C#中數據流(文件流、內存流、網絡流等)相關知識點梳理

基本概念 C#中數據流的應用體現在方方面面,現在針其常用的幾種類進行一次梳理。 數據流包括文件流(FileStream)、內存流(MemoryStream)、網絡流(NetworkStream)以及讀寫流如StreamReader、StreamWriter、BinaryReader和BinaryWriter等。 數據流是什么? …

dns服務 很多問題,后續再研究

慕課網:http://www.imooc.com/video/5220 參考:http://jingyan.baidu.com/article/870c6fc32c028eb03fe4be30.html http://www.tuicool.com/articles/aUNzMfi http://www.07net01.com/linux/dnszhucongfuzhijiquyuchuansong_505144_1373161402.html http…

LINUX下用腳本實現JDK+TOMCAT

這幾天真是累。常常下半夜3點睡覺。是因為這段時間對LINUX下的SHELL編程喜歡上了。 一時弄的忘了睡覺。還好,累沒白累。遍寫了一個JDKTOMCAT的自動安裝,配置的腳本 在這里我把配置出來的成果拿來和大家分享一下。希望有高手來指定一下,我在編…

【圖像處理】——圖像增強Python實現直方圖均衡化

目錄 一、相關概念 1、灰度直方圖概念(hist) 2、灰度概率累積函數(cdf) 3、灰

C#常見編碼方式總結

一、概念 我們知道計算機是基于二進制來表示數據的,那么對于字母和漢字等字符用二進制如何表示? 這就需要用一種編碼方式將這些字母或者符號轉換二進制表示。首先需要對字符集進行編碼表示,每個編碼代表一個固定的字符,然后再將字…

Spring中ApplicationContext加載機制

詳見:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp33 加載器目前有兩種選擇:ContextLoaderListener和ContextLoaderServlet。 這兩者在功能上完全等同,只是一個是基于Servlet2.3版本中新引入的Listener接口實現,…

Codeforces 724 C. Ray Tracing

Codeforces 724 C. Ray Tracing 題目來源 codeforces 題意: 有一些傳感器按輸入坐標分布在圖上,有一道光從(0,0)沿45角出射,遇到邊按反射法則反射,遇到角落結束。 問每一個點被經過的時間,并按照輸入順序輸出。題解&am…

CDN架構以及原理分析

詳見: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp61 在不同地域的用戶訪問網站的響應速度存在差異,為了提高用戶訪問的響應速度、優化現有Internet中信息的流動,需要在用戶和服務器間加入中間層CDN. 使用戶能以最快的速度,從最接近用…

基于VS2019的Eigen庫安裝詳解

概念 Eigen是一個C開源線性代數庫,以提供有關矩陣的的線性代數運算,解方程等功能。Eigen在很多領域如信號處理,圖像處理,深度學習等起到重要作用,學習其操作方法,可以靈活的對線性代數、矩陣和矢量將進行計…