3.3.5.1如何遍歷HashMap對象?尤其請說明通過Iterator遍歷HashMap對象的方法。
建議用這種方式:
Set<Entry<String,String>>entrySet=map.entrySet();
3.3.5.2HashMap是線程安全的還是線程不安全的?HashTable呢?
HashMap是線程不安全的,HashTable是線程安全的。
3.3.5.3 ConcurrentHashMap是線程安全的還是不安全的?請說下該對象底層實現get和put方法的流程。
ConcurrentHashMap 和 HashMap 思路是差不多的,但是因為它支持並發操作,所以要復雜一些。
整個 ConcurrentHashMap 由一個個 Segment 組成,Segment 代表”部分“或”一段“的意思,所以很多地方都會將其描述為分段鎖。注意,行文中,我很多地方用了“槽”來代表一個 segment。
簡單理解就是,ConcurrentHashMap 是一個 Segment 數組,Segment 通過繼承 ReentrantLock 來進行加鎖,所以每次需要加鎖的操作鎖住的是一個 segment,這樣只要保證每個 Segment 是線程安全的,也就實現了全局的線程安全。
get 過程中是沒有加鎖的,那自然我們就需要去考慮並發問題。
put 操作的線程安全性。添加節點到鏈表的操作是插入到表頭的,所以,如果這個時候 get 操作在鏈表遍歷的過程已經到了中間,是不會影響的。當然,另一個並發問題就是 get 操作在 put 之后,需要保證剛剛插入表頭的節點被讀取,這個依賴於 setEntryAt 方法中使用的 UNSAFE.putOrderedObject。