run メソッド内で同期ブロックを使用することは意味がありますか? この run メソッドを含む Runnable のインスタンスではなく、関連するロックを使用している限り、そうだと思いました。stackoverflow に関する同様の質問への回答を読むと、これが確認されたようです。テストするために簡単なコードを書いてみましたが、run メソッド内の同期ブロックはデータの破損を防ぎません。
public class Test {
public Test() {
ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
es.execute(new Runnable() {
@Override
public void run() {
synchronized (lock) {
sum += 1;
}
}
});
}
es.shutdown();
while(!es.isTerminated()) {
}
}
private int sum = 0;
private final Object lock = new Object();
public static void main(String[] args) {
Test t = new Test();
System.out.println(t.sum);
}
}
このコードが間違った結果を生成するのはなぜですか? これは、同期ブロックまたはその他の間違いによるものですか? ここで基本的な何かが欠けているように感じます。