2014-03-13 76 views
3

我有一個ArrayList,我只在同步塊內操作它,我是否也應該使用Collections.synchronizedList? 例子:Java:同步列表

List list = Collections.synchronizedList(new ArrayList());  
// versus List list = new ArrayList();  
synchronized(list) { 
     // my code 
} 
+0

只有一個就足夠了兩個synchronizedList()synchornized塊。只使用'synchronizedList' – rzymek

回答

1
  • 如果你只在​​阻止訪問列表,你不需要synchronizedList()

  • 如果你只使用訪問基本運算(add()remove()等),以及這些操作的唐調用列表「T彼此依賴(即原子性不是問題),如果你希望能夠調用基本操作只能使用synchronizedList()沒有明確​​塊

  • withou牛逼​​塊,也有複合操作(包括迭代)應該是原子,你需要混合操作

+0

非基本操作只是迭代?我總是隻看到這些例子,而不是其他的,所以,「只是爲了迭代而阻止」? – Tatanan

+1

可能有複合操作也應該是原子的,比如'if(!list.contains(...))list.add(...)' – axtavt

+0

@Tata​​nan,「不是基本的」意思是任何操作序列暫時使您的數據處於不一致/無效/非法狀態。典型的例子是從一個銀行賬戶中取錢並存入另一個賬戶的程序。當書籍不正確時,在提款和存款之間有一個瞬間。如果審計員線程在該瞬間恰好看到兩個賬戶,它將報告違規行爲。將這兩個操作放到同步塊中會使它們成爲一個原子單位,並且會阻止審計人員看到處於該狀態的帳戶。 –

1

只需使用synchronized聲明,不需要明確的同步塊:

List list = Collections.synchronizedList(new ArrayList()); 

更改列表中的內容的唯一方法是通過調用添加或刪除,這是現在由於這個聲明而用這些方法的同步版本進行了修飾。

+1

我認爲塊是迭代,排序等所必需的。 我的懷疑實際上只是聲明,如果萬一我把我所有的代碼包裝,我需要聲明列表爲同步。 – Tatanan

1

使用明確的​​塊和使用Collections.synchronizedList(new ArrayList())將等效於互斥。但是,如果你必須遍歷由調用返回的Collections列表中,您必須名單上顯式同步外部反正每Java規範(對不起,SO不會讓我鏈接到它這裏) 。

要考慮的另一件事是開銷。 Collections.synchronizedList(List orig)創建一個新的對象來控制對原始列表實現的訪問。根據您計劃進行此調用的頻率以及您訪問原始列表對象的方式有多種,您可能最好在外部同步它。