HashMap與ConcurrentHashMap的區別


從JDK1.2起,就有了HashMap,正如前一篇文章所說,HashMap不是線程安全的,因此多線程操作時需要格外小心。

在JDK1.5中,偉大的Doug Lea給我們帶來了concurrent包,從此Map也有安全的了。



ConcurrentHashMap具體是怎么實現線程安全的呢,肯定不可能是每個方法加synchronized,那樣就變成了HashTable。

從ConcurrentHashMap代碼中可以看出,它引入了一個“分段鎖”的概念,具體可以理解為把一個大的Map拆分成N個小的HashTable,根據key.hashCode()來決定把key放到哪個HashTable中。

在ConcurrentHashMap中,就是把Map分成了N個Segment,put和get的時候,都是現根據key.hashCode()算出放到哪個Segment中:






測試程序:

  
  
  
          
  1. import java.util.concurrent.ConcurrentHashMap;
  2. public class ConcurrentHashMapTest {
  3. private static ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
  4. public static void main(String[] args) {
  5. new Thread("Thread1"){
  6. @Override
  7. public void run() {
  8. map.put(3, 33);
  9. }
  10. };
  11. new Thread("Thread2"){
  12. @Override
  13. public void run() {
  14. map.put(4, 44);
  15. }
  16. };
  17. new Thread("Thread3"){
  18. @Override
  19. public void run() {
  20. map.put(7, 77);
  21. }
  22. };
  23. System.out.println(map);
  24. }
  25. }


據ConcurrentHashMap.segmentFor的算法,3、4對應的Segment都是segments[1],7對應的Segment是segments[12]。

(1)Thread1和Thread2先后進入Segment.put方法時,Thread1會首先獲取到鎖,可以進入,而Thread2則會阻塞在鎖上:


(2)切換到Thread3,也走到Segment.put方法,因為7所存儲的Segment和3、4不同,因此,不會阻塞在lock():



以上就是ConcurrentHashMap的工作機制,通過把整個Map分為N個Segment(類似HashTable),可以提供相同的線程安全,但是效率提升N倍,默認提升16倍。



ps:總結ConcurrentHashMap就是一個分段的hashtable ,根據自定的hashcode算法生成的對象來獲取對應hashcode的分段塊進行加鎖,不用整體加鎖,提高了效率,hashcode 參考 HashCode的作用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM