gpt4 book ai didi

java - 使用 newSingleThreadExecutor 消除 ExecutorService 中的竞争条件

转载 作者:行者123 更新时间:2023-11-30 06:42:19 25 4
gpt4 key购买 nike

我写了下面的程序来理解赛车:

import java.util.concurrent.*;

class RaceCount
{
static int count = 0;

public static void main(String [] args)
{
ExecutorService executor = Executors.newSingleThreadExecutor();

for (int i = 0; i < 1000; i++)
{
executor.submit(new Callable<String>() {
public String call() throws Exception {
count++; return "Incremented";
}
});
}
executor.shutdown();
System.out.println(count);
}
}

显然,计数远小于 1000。因此,我将 call() 方法签名更改为:

public synchronized String call() throws Exception {

但是,结果仍然小于 1000。如果我使用 newFixedThreadExecutor(1000) 而不是 newSingleThreadExecutor,那么我得到预期的 1000,即使 call() 方法没有前缀 synchronized 关键字。
所以,我的查询是:
1、newSingleThreadExecutor如何同步线程?
2、使用newFixedThreadExecutor为什么不需要同步?

最佳答案

您的问题不是由于竞争条件引起的。它的发生仅仅是因为 executor.shutdown() 在返回之前没有等待完全关闭。

这是来自 java.util.concurrent.ExecutorService.shutdown() 的 javadocs:

...
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

换句话说,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);

关于java - 使用 newSingleThreadExecutor 消除 ExecutorService 中的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53607097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com