みんな。Collections.synchronizedList()メソッドによって返されるArrayListをテストするために、静的クラスを次のように定義しました。
static class ListWriter implements Runnable {
private List<Integer> list;
public ListWriter(List<Integer> list) {
this.list = list;
}
public void run() { // I didn't use synchronized(list) {} block here.
try {
for (int i = 0; i < 20; i++) {
list.add(i);
Thread.sleep(10);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
および以下の試験方法
private static void test1() throws Exception {
List<Integer> list = Collections.synchronizedList(new ArrayList<Integer>());
Thread t1 = new Thread(new ListWriter(list));
Thread t2 = new Thread(new ListWriter(list));
t1.start();
t2.start();
t1.join();
t2.join();
for (int i = 0; i < list.size(); ++i) {
System.out.println(list.get(i));
}
}
結果は通常次のようになります:0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19
ただし、次のようになる場合もあります。
0 0 1 1 2 3 2 3 4 5 4 5 6 7 6 8 7 9 8 10 9 11 10 12 11 13 12 14 13 15 14 15 16 17 16 17 18 19 18 19
これらの結果は、プロセスがスレッドセーフであることを示していますか?重要なのは、Collection.synchronizedList()メソッドによって返される同期されたArrayListを反復処理するために明示的に必要とされる、書き込みスレッドで同期されたブロックを使用しなかったことです。それで、プロセスはスレッドセーフだと思いますか、それとも同期ブロックを使用する必要がありますか?