簡體   English   中英

Java Collection Framework:有些線程安全,有些不安全?

[英]Java Collection Framework: Some thread safe and some not?

我正在學習Java集合框架(而不是並發集合框架),並且我知道有些Collection實現是線程安全的,而有些則不是。

在我讀過的大多數材料中,所有提到的xyz是線程安全的,而abc不是線程安全的。

但是,基於哪種決定是否要確保給定的集合類型(例如,List,Set,Queue,甚至在Map ..中)線程安全,是基於什么邏輯呢?

我的問題是關於“傳統”收集框架的,而不是關於並發收集框架的。

任何了解這一點的投入都會有很大幫助。

線程安全帶來了開銷(盡管在現代VM中,開銷比設計收集框架時要低得多)。 因此,除非特別要求,否則收集不是線程安全的,但JDK1.1收集除外-設計它們時,其理念更像是“以犧牲一些性能為代價,讓錯誤的余地很小”。

Java API的發展分為幾個階段。

JDK1.1

在Java版本1.1中,我們具有數據結構VectorHashtable 它們完全同步,提供了一定級別的線程安全性。

JDK1.2

在Java版本1.2中,引入了collections框架。 基本集合都不是線程安全的(它們不同步任何操作): ArrayListLinkedListHashMapTreeMapSet實現。

但是您可以通過調用Collections.synchronizedMapCollections.synchronizedList等來獲取同步版本。

JDK1.5

在Java版本1.5中,引入了java.util.concurrent框架。 它們包含專門為多線程使用而構造的數據。 這些提供了一定級別的線程安全性。


請注意,即使使用同步的集合,也可以引入數據競爭。 這僅意味着您無法破壞集合的內部結構(集合的所有不變量將被保留)

例如,如果您有一個兩步過程,首先檢查集合中是否包含某些元素,然后在第二步中插入該元素。 如果您沒有為這兩個步驟提供自己的同步,那么如果兩個線程同時執行此操作,則可以將元素添加兩次。

如其他人所述,並發集合具有運行時和潛在的內存開銷,因此將線程安全和不安全集合分離。

在單線程庫中可以找到的大多數數據結構都有幾種線程安全的替代方法。 List是一個值得注意的例外,這可能是因為在應用程序中很少需要並發列表。

對於隊列和堆棧之類的事情,您有很多選擇,因為讓生產者和一個或幾個消費者同時拉動隊列是很平常的事情。 要實現緩存,您可能依賴於映射,這就是為什么並發映射也得到很好支持的原因。

某些數據結構尚未真正在線程安全的API中進行鏡像的事實僅是由於它們通常在多線程上下文中不有用的事實。

原因很可能與性能有關。 多個線程之間的同步是一項昂貴的操作,尤其是在元素數量眾多的情況下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM