在Java類庫中出現的第一個關聯的集合類是 Hashtable。 Hashtable 提供了一種便於使用的、安全執行緒的、關聯的map功能。然而,執行緒安全性付出代價是――Hashtable 的所有方法都是同步的。Hashtable 的後繼者HashMap 是作為JDK1.2中的集合架構的一部分出現的,它通過提供一個不同步的基類和一個同步的封裝器Collections.synchronizedMap
,解決了執行緒安全性問題。通過將基本的功能從執行緒安全性中分離開來,Collections.synchronizedMap 允許需要同步的使用者可以擁有同步,而不需要同步的使用者則不必為同步付出代價。
同步的集合封裝器 synchronizedMap 和 synchronizedList ,有時也被稱作 有條件地安全執行緒――所有單個的操作都是安全執行緒的,但是多個操作組成的操作序列卻可能導致資料爭用,因為在操作序列中控制流程取決於前面操作的結果。例如對於這樣的功能put-if-absent語句塊――如果一個條目不在Map 中,那麼添加這個條目。該功能通過containsKey()
方法和 put() 方法組合起來。要保證原子性操作,就需要對該語句塊加上同步鎖。
Queue介面
java.util 包為集合提供了一個新的基本介面:java.util.Queue,是一個先入先出(FIFO)的資料結構。
PriorityQueue類
BlockingQueue介面
阻塞隊列,它實質上就是一種帶有一點扭曲的 FIFO 資料結構。它提供了可阻塞的put和take方法。如果Queue已經滿了,put方法會被阻塞直到有空間可用;如果Queue是空的,那麼take方法會被阻塞,直到有元素可用。Queue的長度可用有限,也可以無限;無限的Queue永遠不會充滿,所以它的put方法永遠不會被阻塞。阻塞隊列支援生產者-消費者設計模式。BlockingQueue可以使用任意數量的生產者和消費者,從而簡化了生產者-消費者設計的實現。
BlockingQueue介面的幾個主要的實作類別:
ArrayBlockingQueue :一個由數組支援的有界隊列。
LinkedBlockingQueue :一個由連結節點支援的可選有界隊列。
PriorityBlockingQueue :一個由優先順序堆支援的無界優先順序隊列。
DelayQueue :一個由優先順序堆支援的、基於時間的調度隊列。
SynchronousQueue :一個利用 BlockingQueue 介面的簡單聚集(rendezvous)機制。 PriorityBlockingQueue 是具有無界限容量的隊列,它利用所包含元素的 Comparable 排序次序來以邏輯順序維護元素。可以將它看作TreeSet 的可能替代物。對於沒有天然順序的元素,可以為建構函式提供一個Comparator 。不過對PriorityBlockingQueue,有一個要特別注意的地方:從
iterator() 返回的 Iterator 執行個體,元素是不具有優先順序順序的。如果必須以優先順序順序遍曆所有元素,那麼讓它們都通過toArray() 方法並自己對它們排序,像Arrays.sort(pq.toArray()) 。
SynChronousQueue,它根本上不是一個真正的隊列,因為它不會為隊列元素維護任何儲存空間。不過,它維護一個排隊的線程清單,這些線程等待把元素排入佇列或移出隊列。它非常直接的移交工作,減少了生產者和消費者之間移動資料的延遲時間。直接移交同樣會給生產者帶來更多關於任務狀態的反饋資訊:當移交被接受,它就知道消費者已經得到了任務。 因為SynchronousQueue沒有儲存的能力,所以除非另一個線程已經準備好參與移交工作,否則put和take會一直阻塞。比較適合於消費者充足的情況。
CopyOnWriteArrayList 和 CopyOnWriteArraySet ,最適合於讀操作通常大大超過寫操作的情況。