Pocket

ArrayListはスレッドセーフではないんですね。次の2つの問題があります。

(1)add()やremove()がスレッドセーフではない。
複数スレッドから同時に、add()やremove()をするようなプログラムを試したところ、size()と内容が合わなくなることがありました。

(2)イテレーション操作の途中で、add()やremove()すると、ConcurrentModificationExceptionが発生します。なお、同じスレッドでも発生します。同じスレッドなら、すぐに気づくので、イテレーション途中のadd()やremove()は書くことはないんですね。

Collections.synchronizedList

(1)については、synchronizedブロックで、add()やremove()を囲む方法があります。しかし、全ての箇所のadd()やremove()をsynchronizedブロックで囲む必要があります。

そこで、synchronizedListを次のように使います。

listは、add()やremove()など、要素数を変更する操作は、スレッドセーフになりました。

ただし、synchronizedListでも、(2)のConcurrentModificationExceptionは発生します。

この問題には、synchronizedブロックで囲むか、CopyOnWriteArrayListを使います。

CopyOnWriteArrayList

次のように使います。

add()やremove()はスレッドセーフですし、イテレーション途中のadd()やremove()をしても、ConcurrentModificationExceptionは発生しません。

ただし、イテレータを取得後、Listに変更を加えても、イテレータに反映されません。