java - run 方法内的同步块(synchronized block)

标签 java multithreading concurrency synchronized

在 run 方法中使用同步块(synchronized block)有意义吗?我认为只要我使用相关的锁,而不是包含此 run 方法的 Runnable 实例,就可以。阅读 stackoverflow 上类似问题的答案似乎证实了这一点。我尝试编写一些简单的代码来测试它,并且 run 方法内的同步块(synchronized block)并不能防止数据损坏:

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

为什么这段代码会产生不正确的结果?这是因为同步块(synchronized block)还是其他错误?我觉得我在这里缺少一些基本的东西。

最佳答案

您的执行程序可能会遇到某种意外错误。如果发生这种情况,您将不会知道,因为您没有得到任何返回值来检查。

尝试切换到 submit() instead的execute()并存储Future的列表执行者给你的实例。如果最终总和小于 1000,则迭代 future 并 get() 每一个。如果引发异常,您将看到该特定可运行任务发生了什么。

关于java - run 方法内的同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16181600/

相关文章:

java - 正则表达式不选择第一次出现的文本

java - 同步性能

java - 如何在没有 stop() 方法的情况下停止线程?

concurrency - CCR:使用因果关系处理错误的最佳实践

.net - .Net4 gem : The ConcurrentDictionary - Tips & Tricks

java - 如何在HTTP中传递JSON正文放在JAVA中

java - 使用连接运算符 (+) 或 String.format() 方法的字符串连接

java - 带监听器的单例与连接

java - 有条件的公平读写锁

java - Hibernate,将域对象写入接口(interface)以进行延迟加载