Ваша проблема не связана с состоянием гонки.Это происходит просто потому, что executor.shutdown()
не ждет полного выключения перед возвратом.
Это из javadocs java.util.concurrent.ExecutorService.shutdown()
:
...Этот метод не ожидает завершения выполнения ранее представленных задач.Для этого используйте awaitTermination.
Другими словами, System.out.println(count)
выполняется до запуска некоторых задач (хотя он обязательно запускается после отправки всех задач).
Я сделалнебольшое изменение в вашем коде, чтобы сделать этот факт очевидным:
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 1000; i++) {
int e = i;
executor.submit(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executing " + e);
count++;
return "Incremented";
}
});
}
executor.shutdown();
System.out.println("Count: " + count);
}
И вывод выглядит так:
...
Executing 835
Executing 836
Executing 837
Count: 837 <----- Printed before all tasks are run
Executing 838
Executing 839
Executing 840
Executing 841
...
Что ясно показывает, что задачи продолжают выполняться после того, как вы прочиталиcount
переменная.
Если вам необходимо убедиться, что задачи выполняются до того, как вы прочитали обновленное значение, то вам, возможно, придется использовать awaitTermination
, как показано ниже:
executor.shutdown();
executor.awaitTermination(3, TimeUnit.SECONDS); //Pick an appropriate timeout value
System.out.println("Count: " + count);