concurrentHashMap和hashtable的區別,concurrentHashMap在各個版本的jdk中實現有什麼不同
這裡首先先說一下hashtable和hashMap 的區別:
1.HashMap是非synchronized,hashTable 是synchronized;
2.HashMap可以接受為Null的Key和value,而hashtable不能接受;(在hashtable中會提示空指標異常NullPointerException)
這裡再說一下concurrentHashMap:
jdk1.7
一下根據jdk文件翻譯
hashtable 支援檢索的一致性和更新的一致性,然而,儘管所有的操作都是執行緒安全的,更新操作都需要一致性鎖,這個操作會使得鎖住整個表時是都不可以進行操作的。相對於hashtable而言concurrentHashMap 是完全可以操作的依賴於他的執行緒安全而不是他的同步特性。檢索操作例如 get操作通常都不會阻塞,更多的重疊的操作是更新操作,例如 put和remove。檢索操作反映的是最近完成狀態
引入 concurrentLevel 也就是段segment的概念,預設值是16,這樣這些表被劃分然後被一定數量的併發更新操作時互相就不會存在競爭了,因為放置過程中在hashtables中是大體隨機的,在實際的併發過程中是不同的。比較理想的情況是,你可以選定一個值去顧及更多的併發執行緒去進行修改操作。使用一個比所需要的值高很多的值可能會浪費空間和時間,而使用一個顯然低很多的值可能導致執行緒爭用。
concurrentHashMap實現了Map和Iterator中的所有方法,類似hashtable而不類似HashMap,不允許用Null用於設定Key或者value。
可以參考這個 https://my.oschina.net/hosee/blog/639352 帖子,詳細的介紹了其中的原理。
那麼,1.6和1.7中有什麼不同呢?
1.建立segment的過程中有些不同,和jdk6相比,在jdk7中,除了第一個segment之外,其餘的segment的建立都是採用延時建立的方式:也就是說在put操作之前都需要先判斷key對應的segment是否已經建立,如果沒有建立的話,使用ensureSegment來進行建立,這裡並沒有使用鎖的概念來建立,而是使用了Unsafe物件的getObjectVolatile()提供的原子讀語義結合CAS來確保Segment建立的原子性。(這裡unsafe)