コレクションがあり、多くのスレッドを生成して、その要素に対して重い作業を行いたいと考えています。コレクションの各要素は、一度だけ処理する必要があります。同期をできるだけ最小限に抑えたいので、次のコードを思いつきました。
//getting the iterator is actually more complicated in my specific case
final Iterator it = myCollection.terator();
Thread[] threads = new Thread[numThreads];
for( int i = 0; i < numThreads; i++ ) {
threads[i] = new Thread(new Runnable() {
public void run() {
Object obj = null;
while(true) {
synchronized (it) {
if(it.hasNext())
obj = it.next();
else
return;
}
//Do stuff with obj
}
}
});
threads[i].start();
}
for (Thread t : threads)
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
注:スレッドは、「obj を操作している」間に項目を追加または削除してコレクションを変更することはありません。
Collection.synchronizedStuff..
このコードは、人々がコレクション自体を同期する、 を使用する、またはイテレーション全体を同期する傾向がある場所で見つけた例とはまったく異なります。私の調査中に、使用して実装されたおそらくより良い代替案も見つかりましThreadPoolExecutor
たが、それについては少し忘れましょう...
上記の注 1 を考慮すると、上記のコードは安全ですか? そうでない場合、なぜですか?