7

私のコードスローは例外に従います:

java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
        at java.util.LinkedList$ListItr.next(LinkedList.java:696)
        at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
        at java.util.LinkedHashSet.<init>(LinkedHashSet.java:152)
        ...

私はConcurrentLinkedHashSetそれを修正したい、

しかし、私はでしか見つかりませんでしConcurrentSkipListSetjava.util.concurrent、これはTreeSet、ではありませんLinkedHashSet

JDK6.0ConcurrentLinkedHashSetに簡単にアクセスする方法はありますか?

手伝ってくれてありがとう :)

4

4 に答える 4

10

ConcurrentModificationExceptionは、考えている形式の並行性とは何の関係もありません。これは、コレクションを反復処理しているときに、誰か(おそらくあなた自身のコード-それは十分に頻繁に発生します;))がコレクションを変更している、つまりいくつかの値を追加/削除していることを意味します。

コレクション自体ではなく、コレクションから値を削除するためにIteratorを使用していることを確認してください。

編集:本当に別のスレッドが同時にコレクションにアクセスしている場合、標準ライブラリから取得する弱い同期は、1回の追加だけでなく操作の全期間にわたってコレクションをブロックする必要があるため、とにかく役に立ちません。削除する!つまり、

synchronize(collection) {
   // do stuff here
}
于 2011-03-13T17:06:33.023 に答える
4

を使用して、いつでも同期コレクションを作成できますCollections.synchronizedMap(myMap);。ただし、反復中にマップを変更しようとすると(これがエラーの原因であると私は推測しています)、それでも問題が発生します。

同期マップのドキュメントから:

指定されたマップに裏打ちされた同期された(スレッドセーフな)マップを返します。シリアルアクセスを保証するために、バッキングマップへのすべてのアクセスが返されたマップを介して実行されることが重要です。

コレクションビューのいずれかを反復処理するときは、ユーザーが返されたマップで手動で同期することが不可欠です...このアドバイスに従わないと、非決定的な動作が発生する可能性があります。

それの訳は

  • 通常、並行コレクションは実際にアトミックなget / putを保証しますが、反復中にコレクション全体をロックすることはありません。これは遅すぎます。反復に対する同時実行性の保証はありません。これは、実際にはマップに対する多くの操作です。

  • 正しい動作を判断することは不可能であるため、反復中に変更している場合、実際には並行性ではありません。たとえば、コレクションから(おそらく次の値)を削除してhasNext == trueを返すイテレータをどのように調整しますか?

于 2011-03-13T16:57:43.583 に答える
2

ConcurrentLinkedHashMapがあります-https://code.google.com/p/concurrentlinkedhashmap/

java.util.Collections.newSetFromMap(map)を使用して、そこからSetを作成できます。

于 2013-12-13T10:50:06.627 に答える
0

残念ながら違います。ConcurrentHashMapとConcurrentLinkedQueueをラップして独自に実装することもできますが、これでは値を簡単に削除できません(キュー内のすべてを反復処理する必要があるため、削除はO(N)になります)...

LinkedHashSetを何に使用していますか?代替案を提案できるかもしれません...

于 2011-03-13T16:54:29.183 に答える