Java 中ConcurrentHashMap的完成。本站提示廣大學習愛好者:(Java 中ConcurrentHashMap的完成)文章只能為提供參考,不一定能成為您想要的結果。以下是Java 中ConcurrentHashMap的完成正文
ConcurrentHashMap(簡稱CHM)是在Java 1.5作為Hashtable的替換選擇新引入的,是concurrent包的主要成員。在Java 1.5之前,假如想要完成一個可以在多線程和並發的法式中平安應用的Map,只能在HashTable和synchronized Map當選擇,由於HashMap其實不是線程平安的。但再引入了CHM以後,我們有了更好的選擇。CHM不只是線程平安的,並且比HashTable和synchronizedMap的機能要好。絕對於HashTable和synchronizedMap鎖住了全部Map,CHM只鎖住部門Map。CHM許可並發的讀操作,同時經由過程同步鎖在寫操作時堅持數據完全性。我們曾經在Top 5 Java Concurrent Collections from JDK 5 and 6中進修了CHM的基本常識,在這篇博客中我將引見以下幾點:
Java中ConcurrentHashMap的完成
CHM引入了朋分,並供給了HashTable支撐的一切的功效。在CHM中,支撐多線程對Map做讀操作,而且不須要任何的blocking。這得益於CHM將Map朋分成了分歧的部門,在履行更新操作時只鎖住一部門。依據默許的並發級別(concurrency level),Map被朋分成16個部門,而且由分歧的鎖掌握。這意味著,同時最多可以有16個寫線程操作Map。試想一下,由只能一個線程進入釀成同時可由16個寫線程同時進入(讀線程簡直不受限制),機能的晉升是不言而喻的。但因為一些更新操作,如put(),remove(),putAll(),clear()只鎖住操作的部門,所以在檢索操作不克不及包管前往的是最新的成果。
另外一個主要點是在迭代遍歷CHM時,keySet前往的iterator是弱分歧和fail-safe的,能夠不會前往某些比來的轉變,而且在遍歷進程中,假如曾經遍歷的數組上的內容變更了,不會拋出ConcurrentModificationExceptoin的異常。
CHM默許的並發級別是16,但可以在創立CHM時經由過程結構函數轉變。毫無疑問,並發級別代表著並發履行更新操作的數量,所以假如只要很少的線程會更新Map,那末建議設置一個低的並發級別。別的,CHM還應用了ReentrantLock來對segments加鎖。
Java中ConcurrentHashMap putifAbsent辦法的例子
許多時刻我們願望在元素不存在時拔出元素,我們普通會像上面那樣寫代碼
synchronized(map){ if (map.get(key) == null){ return map.put(key, value); } else{ return map.get(key); } }
下面這段代碼在HashMap和HashTable中是好用的,但在CHM中是有失足的風險的。這是由於CHM在put操作時並沒有對全部Map加鎖,所以一個線程正在put(k,v)的時刻,另外一個線程挪用get(k)會獲得null,這就會形成一個線程put的值會被另外一個線程put的值所籠罩。固然,你可以將代碼封裝到synchronized代碼塊中,如許固然線程平安了,但會使你的代碼釀成了單線程。CHM供給的putIfAbsent(key,value)辦法原子性的完成了異樣的功效,同時防止了下面的線程競爭的風險。
甚麼時刻應用ConcurrentHashMap
CHM實用於讀者數目跨越寫者時,當寫者數目年夜於等於讀者時,CHM的機能是低於Hashtable和synchronized Map的。這是由於當鎖住了全部Map時,讀操作要期待對統一部門履行寫操作的線程停止。CHM實用於做cache,在法式啟動時初始化,以後可以被多個要求線程拜訪。正如Javadoc解釋的那樣,CHM是HashTable一個很好的替換,但要記住,CHM的比HashTable的同步性稍弱。
總結
如今我們曉得了甚麼是ConcurrentHashMap和甚麼時刻該用ConcurrentHashMap,上面我們來溫習一下CHM的一些症結點。
以上就是Java中CHM的完成和應用場景,願望能贊助到年夜家!感謝年夜家對本站的支撐!