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);
}
4

1 に答える 1

7

あなたが言ったように、リストはすでに同期されているので、removeStringメソッドも同期する必要はありませんsynchronized

ただし、メソッドの 1 つに非アトミック操作が含まれている場合 (たとえば、リストに何かが含まれているかどうかを確認し、それに応じてリストを変更したい場合)、別の同期レイヤーを追加する必要がある場合があります。

最後に、この方法に気付いていないようです。

public synchronized void removeString(String s)

別のロックで同期します (で同期しますthis)。上記の例に戻ると、次のように記述します。

public void someMethod() {
    synchronized(listOfString) { //use the same lock!
        if(listOfString.size() == 123) {
            listOfString.add("lucky day");
        }
    }
}
于 2013-05-17T14:41:38.747 に答える