1. 程式人生 > >為什麼java.util.concurrent 包裡沒有併發的ArrayList實現?

為什麼java.util.concurrent 包裡沒有併發的ArrayList實現?

原文連結 作者:Stephen C 譯者:鄭旭東  校對:方騰飛

問:JDK 5在java.util.concurrent裡引入了ConcurrentHashMap,在需要支援高併發的場景,我們可以使用它代替HashMap。但是為什麼沒有ArrayList的併發實現呢?難道在多執行緒場景下我們只有Vector這一種執行緒安全的陣列實現可以選擇麼?為什麼在java.util.concurrent 沒有一個類可以代替Vector呢?

答:我認為在java.util.concurrent包中沒有加入併發的ArrayList實現的主要原因是:很難去開發一個通用並且沒有併發瓶頸的執行緒安全的List。

像ConcurrentHashMap這樣的類的真正價值(The real point / value of classes)並不是它們保證了執行緒安全。而在於它們在保證執行緒安全的同時不存在併發瓶頸。舉個例子,ConcurrentHashMap採用了鎖分段技術和弱一致性的Map迭代器去規避併發瓶頸。

所以問題在於,像“Array List”這樣的資料結構,你不知道如何去規避併發的瓶頸。拿contains() 這樣一個操作來說,當你進行搜尋的時候如何避免鎖住整個list?

另一方面,Queue 和Deque (基於Linked List)有併發的實現是因為他們的介面相比List的介面有更多的限制,這些限制使得實現併發成為可能。

CopyOnWriteArrayList是一個有趣的例子,它規避了只讀操作(如get/contains)併發的瓶頸,但是它為了做到這點,在修改操作中做了很多工作和修改可見性規則。 此外,修改操作還會鎖住整個List,因此這也是一個併發瓶頸。所以從理論上來說,CopyOnWriteArrayList並不算是一個通用的併發List。