2

リストが doSomething() で変更された場合、このコードは同時変更例外をスローします。コードを同期ブロックで囲むことで回避することは可能ですか?

List l = Collections.synchronizedList(new ArrayList());

// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
  doSomething(i.next());
}
4

6 に答える 6

7
  • リストからアイテムを削除する場合は、iterator.remove()代わりに呼び出すことで実行できますlist.remove(iterator.next())

  • アイテムを追加する場合 - まあ、反復リストのコピーを作成し、そこに追加します

  • 上記のコード スニペットが同じメソッドの一部である場合、同期リストまたは同期ブロックは必要ありません。他のスレッドはローカル リストにアクセスできません。

于 2010-02-12T06:49:36.837 に答える
3

インターフェイスを介して変更する場合は、それを繰り返しながら変更できます。要素を削除するために使用できます。CollectionIteratorIterator.remove()

于 2010-02-12T06:49:59.550 に答える
0

Iteratorとについて他の人に同意しremove()ます。


同期については、同期が異なるスレッド間の相互作用を制御するように設計されていることを追加したいと思います。

オブジェクトが複数のメソッドを同期し、1つが別のメソッドを呼び出すのが一般的です。そのため、言語設計者は、同期時に同じスレッドが自分でブロックされないようにすることを決定しました。

また、考えてみると、自分を待っているスレッドがブロックされているので、壮大な飢餓の視点があります!;-)

したがって、これはあなたの質問の1つに答えます:コードを同期することによって問題を回避することは不可能です。

于 2010-02-12T07:30:00.493 に答える
0

反復処理中は変更できません。ここでは同期は役に立ちません。

編集:イテレータにメソッドがあることを忘れていましたremove。なので取り外し可能です。

于 2010-02-12T06:47:28.410 に答える
0
List l = Collections.synchronizedList(new ArrayList());

synchronized(l) { 
   // normal iteration -- can throw ConcurrentModificationException
   // may require external synchronization
   for (Iterator i=list.iterator(); i.hasNext(); ) {
      doSomething(i.next());
   }
}
于 2013-10-25T06:49:02.900 に答える
0

CopyOnWriteArrayList同期配列リストの代わりに使用

于 2010-02-12T07:45:26.810 に答える