25

dos.oracle.comでこれを見つけました

public static List synchronizedList(リスト リスト)

指定されたリストに基づく同期 (スレッドセーフ) リストを返します。シリアル アクセスを保証するには、バッキング リストへのすべてのアクセスが、返されたリストを介して行われることが重要です。ユーザーは、返されたリストを反復処理するときに手動で同期することが不可欠です。

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

私の質問は:Collections.synchronizedList();既に同期されたリストを返すことになっている場合、リストを同期して反復する必要があるのはなぜですか?

2 つのスレッドでリストにアクセスするだけです。1 つのスレッドは追加するだけで、もう 1 つのスレッドは取得および削除します。このシナリオで使用することをお勧めする他のクラスは何ですか?

読んでくれてありがとう。

4

2 に答える 2

30

同期されているリストはaddremoveなどの操作が同期されているため、アトミックであることを意味するだけです。ただし、反復はそうではなく、adds別のスレッドが反復しているときにスレッドが実行されると、ConcurrentModificationException が発生する可能性があります。

反復ブロックを手動で同期することにより、反復中にリストが変更されないようにします。

1 つの代替手段は、その後の変更に関係なく、反復が開始されたときにわかっていたリストを反復処理する反復子提供するaを使用することです。CopyOnWriteArrayListただし、リストの内容を頻繁に変更する必要がある場合、そのコレクションはあまり効率的ではありません。

于 2013-08-01T12:45:41.047 に答える