0

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);
    }
}

このコードが間違った結果を生成するのはなぜですか? これは、同期ブロックまたはその他の間違いによるものですか? ここで基本的な何かが欠けているように感じます。

4

2 に答える 2

1

エグゼキュータで何らかの予期しないエラーが発生する可能性があります。それが起こった場合、チェックする戻り値を取得していないため、それを知ることはできません。

execute() の代わりに submit() に切り替えて、Executor が提供するFutureインスタンスのリストを保存してみてください。最終的な合計が 1000 未満の場合は、先物を反復し、それぞれを get() します。例外が発生した場合、その特定の実行可能なタスクで何が起こったのかがわかります。

于 2013-04-24T01:41:32.133 に答える