2015-02-06 86 views
1

如果我創建這樣的列表:爲什麼要同步一個同步列表?

List<MyObj> myobjs = Collections.synchronizedList(new ArrayList<MyObj>()); 

相關的文檔聲稱,此返回的列表的需要,以遍歷元件進行同步。但是,我可以同步一個常規列表並使用同步塊保護它。那麼,爲什麼我需要一個「synchronizedList」?

返回由指定的 列表支持的同步(線程安全)列表。爲了保證串行訪問,通過返回列表完成對後備列表訪問的所有訪問是至關重要的。

當務之急是用戶迭代它時,返回 名單上手動同步:

List list = Collections.synchronizedList(new ArrayList()); 
     ... 
    synchronized (list) { 
     Iterator i = list.iterator(); // Must be in synchronized block 
     while (i.hasNext()) 
      foo(i.next()); 
    } 

不遵循此建議將導致無法確定的 行爲。如果指定的列表 是可序列化的,則返回的列表將是可序列化的。

參數:列表列表將被「包裝」在同步列表中。 返回:指定列表的同步視圖。

+1

它已經在這裏回答:http://stackoverflow.com/questions/9468187/collections-synchronizedlist-and-synchronized。簡單的操作保證是線程安全的,但迭代不是一個簡單的操作。 – 2015-02-06 20:02:25

+0

我同意這些問題是相似的,但不完全重複。即我詢問同步列表的用途是什麼,如果你還需要同步,並且romsky詢問在使用SynchronizedList時同步的目的是什麼。 – paiego 2015-02-06 20:14:52

+0

因爲它只能進行簡單操作的同步......你會怎麼做? – 2015-02-06 20:18:49

回答

3

synchronizedList是一種便捷的包裝,可以避免在大多數情況下手動同步,但在迭代時不能進行手動同步。

在正常的非同步列表中,如果多線程使用它,則需要始終手動進行同步,因此使用synchronizedList可能會很方便。

需要synchronizedList的情況下,如果您將列表傳遞給某些未在列表中同步的第三方代碼,但仍需要同步。但是,這很容易出錯,因爲您依賴於第三方代碼不會遍歷列表或使用其他非原子操作的事實,因此如果可能的話,最好完全避免這種情況(例如,通過複製列表)。

+1

謝謝......來自romski的文章,「同樣重要的是要注意,任何使用迭代器(例如Collections.sort())的方法也需要封裝在同步塊中。」 – paiego 2015-02-06 20:15:50