ConcurrentHashMap
ConcurrentHashMap是HashMap在並發環境下的版本,大家可能要問,既然已經可以通過Collections.synchronizedMap獲得安全執行緒的映射型容器,為什麼還需要ConcurrentHashMap呢。因為通過Collections工具類獲得的安全執行緒的HashMap會在讀寫資料時對整個容器物件上鎖,這樣其他使用該容器的線程無論如何也無法再獲得該對象的鎖,也就意味著要一直等待前一個獲得鎖的線程離開同步代碼塊之後才有機會執行。實際上,HashMap是通過雜湊函數來確定存放索引值對的桶(桶是為瞭解決雜湊衝突而引入的),修改HashMap時並不需要將整個容器鎖住,只需要鎖住即將修改的“桶”就可以了。HashMap的資料結構如下圖所示。
此外,ConcurrentHashMap還提供了原子操作的方法,如下所示: putIfAbsent:如果還沒有對應的索引值對映射,就將其添加到HashMap中。 remove:如果鍵存在而且值與目前狀態相等(equals比較結果為true),則用原子方式移除該索引值對映射 replace:替換掉映射中元素的原子操作 CopyOnWriteArrayList
CopyOnWriteArrayList是ArrayList在並發環境下的替代品。CopyOnWriteArrayList通過增加寫時複製語義來避免並發訪問引起的問題,也就是說任何修改操作都會在底層建立一個列表的副本,也就意味著之前已有的迭代器不會碰到意料之外的修改。這種方式對於不要嚴格讀寫同步的情境非常有用,因為它提供了更好的效能。記住,要盡量減少鎖的使用,因為那勢必帶來效能的下降(對資料庫中資料的並發訪問不也是如此嗎。如果可以的話就應該放棄悲觀鎖而使用樂觀鎖),CopyOnWriteArrayList很明顯也是通過犧牲空間獲得了時間(在電腦的世界裡,時間和空間通常是不可調和的矛盾,可以犧牲空間來提升效率獲得時間,當然也可以通過犧牲時間來減少對空間的使用)。
Queue
隊列是一個無處不在的美妙概念,它提供了一種簡單又可靠的方式將資源分發給處理單元(也可以說是將工作單元分配給待處理的資源,這取決於你看待問題的方式)。實現中的並發編程模型很多都依賴隊列來實現,因為它可以線上程之間傳遞工作單元。
Java 5中的BlockingQueue就是一個在並發環境下非常好用的工具,在調用put方法向隊列中插入元素時,如果隊列已滿,它會讓插入元素的線程等待隊列騰出空間;在調用take方法從隊列中取元素時,如果隊列為空白,取出元素的線程就會阻塞。