Java 为什么不是';我的同步方法不起作用吗?

Java 为什么不是';我的同步方法不起作用吗?,java,concurrency,executorservice,Java,Concurrency,Executorservice,简单地说,我试图看到使用sychronized关键字与在没有锁的线程上运行函数的区别 在此代码中: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.IntStream; public class mainClass { static int count=0; public static void main(String[]

简单地说,我试图看到使用sychronized关键字与在没有锁的线程上运行函数的区别

在此代码中:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;


public class mainClass {
static int count=0;

public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(2);
    Runnable r =new Runnable() {

        public synchronized void run() {
            count = count + 1;
        }
    };
    IntStream.range(0, 10000)
            .forEach(i -> executor.submit(r::run));

    executor.shutdown();

    System.out.println(count);  // 10000

}
}
它不能像我预测的那样工作,它在40%的运行中返回10000。为什么呢?问题在哪里? 我认为函数运行一次只由一个线程运行,所以应该没有问题,但显然我错了。

ExecutorService#shutdown
不会等待任务完成。您应该使用
等待终止

IntStream.range(0,10000)
.forEach(i->executor.submit(r::run));
executor.shutdown();
执行者。等待终止(1,时间单位。分钟);// 
ExecutorService#shutdown
不会等待任务完成。您应该使用
等待终止

IntStream.range(0,10000)
.forEach(i->executor.submit(r::run));
executor.shutdown();

执行者。等待终止(1,时间单位。分钟);//并移除关机:)@VeselinDavidov您仍然需要关机<代码>等待终止
“在关闭请求后,直到所有任务完成执行为止”您不会删除关闭。在调用
shutdown
之后调用
awaitTermination
正是解决这个问题的方法。@ptomli在这个简单的用例中,您并不完全需要
shutdown
awaitTermination
只需等待一分钟,然后所有任务都很可能完成;)只是为了100%准确。不过,使用shutdown绝对是正确的方法。@Ben我只需要测试一下
waittermination
是否在没有事先调用
shutdown
的情况下被阻止。似乎是的,我觉得医生们并不是毫不含糊的。很高兴知道。然后移除关机:)@VeselinDavidov你仍然需要关机<代码>等待终止
“在关闭请求后,直到所有任务完成执行为止”您不会删除关闭。在调用
shutdown
之后调用
awaitTermination
正是解决这个问题的方法。@ptomli在这个简单的用例中,您并不完全需要
shutdown
awaitTermination
只需等待一分钟,然后所有任务都很可能完成;)只是为了100%准确。不过,使用shutdown绝对是正确的方法。@Ben我只需要测试一下
waittermination
是否在没有事先调用
shutdown
的情况下被阻止。似乎是的,我觉得医生们并不是毫不含糊的。不过很高兴知道。
IntStream.range(0, 10000)
        .forEach(i -> executor.submit(r::run));

executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTE); // <!-- HERE