8

java.util Collection クラスを使用するときは常に、あるスレッドがイテレータを使用してコレクションをトラバースしている間に別のスレッドがコレクションを変更すると、iterator.hasNext()orへの呼び出しiterator.next()は をスローしConcurrentModificationExceptionます。synchronizedコレクション ラッパー クラスSynchronizedMapでさえ、SynchronizedList条件付きでのみスレッド セーフです。つまり、個々の操作はすべてスレッド セーフですが、制御の流れが前の操作の結果に依存する複合操作は、スレッド化の問題が発生する可能性があります。問題は、パフォーマンスに影響を与えずにこの問題を回避する方法です。注:承知しておりCopyOnWriteArrayListます。

4

4 に答える 4

2

上記のようにCopyOnWriteArrayListまたはなどを使用するか、CASで動作するクラスを使用できます。ConcurrentHashMapAtomic*

クラスを知らなかった場合はAtomic*、一見の価値があります。この質問をチェックアウトできます。

したがって、あなたの質問に答えるには、タスクに適したツールを選択する必要があります. あなたは私たちと文脈を共有していないので、私は推測することができます. 場合によっては、CAS のパフォーマンスが向上し、別の状況では並行コレクションのパフォーマンスが向上します。

不明な点がある場合は、公式の Oracle Trails: Lesson: Concurrencyをいつでも確認できます。

于 2012-11-10T14:19:46.520 に答える
1

おもしろい質問をされたと思います。
たとえば、他の人が提案したConcurrentHashMapが役立つかどうかを考えてみましたが、ロックがセグメントベースであるためわかりません。
この場合、私が行うことは、あなたの質問をよく理解したことを願っていますが、ReaderWriterLockを使用してコレクションへのアクセスをロックすることです。
私がこのロックを選択した理由は、これにはロックが必要だと感じているためです(説明したように、反復は複数の操作で構成されています)、
また、リーダースレッドの場合、コレクションで作業しているライタースレッドがない場合は、ロックを待機したくないためです。@Adam Aroldのおかげで、「同期デコレータ」を提案されたことに注意しましたが、このデコレータは同期を使用し、NリーダーとMライターのケースを区別しないため、ニーズに対して「強すぎる」と感じます。

于 2012-11-10T14:25:46.117 に答える
1

これは、「標準」の Java コレクションが同期されていないため、スレッドセーフではないためです。コレクションにアクセスする複数のスレッドで作業する場合は、java.util.concurrentパッケージを確認する必要があります。

このパッケージがないと、Java 5 より前では、手動で同期を実行する必要がありました。

synchronized(list) {
   Iterator i = list.iterator(); // Must be in synchronized block
   while (i.hasNext())
       foo(i.next());
}

または使用して

Collections.synchronizedList(arrayList);

しかし、どちらも完全なスレッド セーフ機能を実際に提供することはできませんでした。

このパッケージを使用すると、コレクションへのすべてのアクセスがアトミックに行われ、いくつかのクラスがアクセスされますprovide a snapshot of the state of the list when the iterator was constructed(「 」を参照してくださいCopyOnWriteArrayListCopyOnWriteArrayList読み取りは高速ですが、多数の書き込みを実行している場合、パフォーマンスに影響する可能性があります。

したがって、 が望ましくない場合は、 which offers をCopyOnWriteArrayList見てください。コレクション全体をトラバースするよりも頻繁に特定のインデックスの要素にアクセスする必要がない限り、これはあらゆる点で効率的です。ConcurrentLinkedQueuea "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator

別のオプションは、ConcurrentSkipListSetどちらprovides expected average log(n) time cost for the contains, add, and remove operations and their variants. Insertion, removal, and access operations safely execute concurrently by multiple threadsiterators are weakly consistent同様です。

どの同時 (スレッドセーフ) コレクションは、最も多く実行する操作の種類によって異なります。これらはすべて Java Collection フレームワークの一部であるため、必要なときにいつでも交換できます。

于 2012-11-10T14:19:13.447 に答える