0

これについての私の理解では、synchronizedブロックは、そのブロックが終了するまで他のスレッドがアクセスできないようにするということです。つまり、現在実行中のクラス (?) によって保持されているロックを介して、それまで保留にされます。

したがって、リストを反復処理し、その直後にそのリストをfor呼び出すブロックをブロックでラップします。これら 2 つの操作セットの間に他のスレッドをリストに追加する余裕がないためです。これは、次のように言うドキュメントに従っています。clear()synchronized

ユーザーは、返されたコレクションを反復するときに手動で同期することが不可欠です...

addただし、リストにいるときに同じことをする必要があるかどうかはわかりません。私の場合、add異なるスレッドからの操作の順序は重要ではないため、そうではないと思います。私が確信が持てないのは、synchronized 変更解除操作が悪影響を与える可能性があるかどうかだと思いますか?

4

2 に答える 2

2

連携する必要のある複数の操作がある場合にのみ、ロックが必要です。イテレータの場合、ループの存続期間中にすべての操作を実行します。

追加が任意の順序で発生する可能性がある場合、追加のロックは必要ありません。

リストを反復処理してからclear()を呼び出すforブロックをラップします

ユースケースからすると、BlockingQueue(同期されていなくてもスレッドセーフ)またはExecutorService(スレッドプールとキューを組み合わせる)の方が適しているように思われます。

于 2012-12-18T16:00:31.210 に答える
0

コレクション自体で同期することが重要です

Collection c = Collections.synchronizedCollection(myCollection);
     ...
synchronized (c) {
     for(Object o : c) {
      ....  
}

のメソッドを呼び出す他のスレッドcは、ブロックを離れるまでブロックされます。他の同期は必要ありません

于 2012-12-18T15:58:55.200 に答える