Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java run方法中的同步块_Java_Multithreading_Concurrency_Synchronized - Fatal编程技术网

Java run方法中的同步块

Java run方法中的同步块,java,multithreading,concurrency,synchronized,Java,Multithreading,Concurrency,Synchronized,在run方法中使用同步块有意义吗?我认为可以,只要我使用的是相关的锁,而不是包含这个run方法的Runnable实例。阅读stackoverflow上类似问题的答案似乎证实了这一点。我尝试编写一些简单的代码来测试它,run方法中的synchronized块无法防止数据损坏: public class Test { public Test() { ExecutorService es = Executors.newCachedThreadPool(); f

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

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);
    }
}
公共类测试{
公开考试(){
ExecutorService es=Executors.newCachedThreadPool();
对于(int i=0;i<1000;i++){
执行(新的Runnable(){
@凌驾
公开募捐{
已同步(锁定){
总和+=1;
}
}
});
}
es.shutdown();
而(!es.isTerminated()){
}
}
私有整数和=0;
私有最终对象锁=新对象();
公共静态void main(字符串[]args){
测试t=新测试();
系统输出打印项次(t.sum);
}
}

为什么此代码生成错误的结果?这是因为同步块还是其他错误?我觉得我缺少了一些基本的东西。

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


尝试切换到of execute(),并存储executer提供给您的实例列表。如果最终的总和小于1000,则迭代futures并获取()每个值。如果引发异常,您将看到该特定可运行任务发生了什么

除了您的简单示例(看起来还可以)之外,您还应该注意Runnable中的同步,以防止当一个Runnable等待某个资源被队列中的另一个Runnable释放时,它们彼此阻塞,因为当前正在等待的Runnable必须先完成,所以该资源稍后才被另一个Runnable释放


但是,如果有足够的工作线程执行作业,这种情况就不太可能发生。

你做得很好。我想你可能会被Java内存模型咬到。你在使用哪个JRE?奇怪的是,我得到了900到1000之间的随机结果。使用
es.submit()
并在返回的将来运行main
.get()
,然后打印总数。