2013-05-27 72 views
3

我不確定我是否理解Java中的同步列表。假設我有以下幾點:同步列表如何工作?

List<Integer> numbers = Collections.synchronizedList(new ArrayList<Integer>()); 

// Assumption: This is running on a separate thread 
public void add() { 
     numbers.add(new Random().nextInt(100)); 
} 

// This is also running on a separate thread 
public void doSomething() { 
     synchronized(numbers) { 
      for (int i : numbers) {} 
     } 
} 

基本上,將add()能如果調用doSomething()到號碼添加到列表中?如果我使用public synchronized void add()public synchronized void doSomething(),會發生什麼?

我正在使用UDP套接字服務器,並且我打算將客戶端存儲在ArrayList中。我會有多個線程可以讀取,寫入和修改這個列表。我該怎麼做?

回答

2

如果doSomething()被調用,那麼add()能夠將數字添加到列表中嗎?

不,直到線程調用doSomething()離開同步塊。

如果我改用public synchronized void add()和public synchronized void doSomething(),會發生什麼?

假設這些是唯一使用該列表的地方,效果將是相同的。但是你會同步包含列表的對象而不是在列表本身上同步。

基本上,所有對共享狀態的訪問都必須在同一個鎖上進行同步。你選擇你喜歡的鎖。您可以使用像CopyOnWriteArrayList這樣的併發集合,而不是使用同步列表或同步方法。

+0

我很困惑;否則別人會說。 –

+1

@BrandonSmith - 我錯了,我改變了我的答案。 –

+0

@BrandonSmith,這個答案清楚地解釋了你的代碼行爲,因爲在這兩種情況下,兩個操作在同一個對象上是同步的。 – techuser

0

這應該很好。根據Collections.synchronizedList的文檔,列表增變器方法(add()等)在列表對象本身上同步。由於你的迭代循環也在​​區塊內,所以一切都會好的。

+0

那我該怎麼做? –

+0

@@ BrandonSmith - 忘記我早些時候的答案。你的代碼很好。 –

+0

我不確定「你的代碼是好的」是什麼意思。爲了明確說明,如果doSomething()正在處理,那麼add()將不能將數字添加到列表中。 – techuser