2013-05-17 32 views
4

所以我有一個由多個線程訪問下面的列表:我需要同步兩種方法和對象

ArrayList<String> listOfString = Collections.synchronizedList(new ArrayList<String>());

我知道,當我遍歷列表我要像這樣同步:

synchronized(listOfString) 
{ 
    for(String s : listOfString) System.out.println(s); 

    listOfString.clear(); 
} 

,如果我要刪除的東西,難道我這樣做什麼:

public void removeString(String s) 
{ 
    listOfString.remove(s); 
} 

或本:

public synchronized void removeString(String s) 
{ 
    listOfString.remove(s); 
} 
+2

個人而言,如果我要去可以通過'List'迭代的地方......我不與'Collections.synchronizedList打擾()'調用,只需在'List'同步的*所有*操作。這是旁邊的人誰讀/觸摸代碼更加明確。 –

回答

7

正如你所說,該列表已經被同步,所以你removeString方法並不需要是​​了。

不過請注意,如果你的方法之一包含非原子操作(說要檢查,如果你的列表中包含的東西,然後相應地修改列表),你可能需要添加同步的另一層。

最後,你似乎沒有注意到,這個方法:

public synchronized void removeString(String s) 

同步在不同的鎖(也同步上this)。所以回到我上面給的例子,你會寫:

public void someMethod() { 
    synchronized(listOfString) { //use the same lock! 
     if(listOfString.size() == 123) { 
      listOfString.add("lucky day"); 
     } 
    } 
} 
+0

哦,我打字是第二部分。哦,+1 – Riking

+0

+1,synchronizedList只關心使列表本身線程安全,但在問題中已經有一個多部分操作(迭代和清除),這可能是原子的。 – Medo42