java ThreadPoolExecutor 中奇怪的竞争条件

问题描述 投票:0回答:1

我正在尝试制作一个必须异步发送请求的 api 检查应用程序

(One replica = one thread that processes it)

启动时 - 创建包含副本的列表

List<Bot>
。每个副本
Bot
只能用一个线程来管理。所有副本都以固定大小在
Executors.newFixedThreadPool(n)
中执行,每个副本执行 2 个 http 请求并将响应保存到自身中。

执行后,我看到来自不同副本的重复请求有 1-2% (服务器发送了正确的数据,我发誓)

机器人实体:

public class Bot 
{
    private final Statistic statisic = new Statistic();
    private final Object mutex = new Object();
    private String responseData;    

    void run() 
    {
        synchronized(mutex) {
          // first http call -> save to responseData
          // second http call (use previous responseData as param) -> result
          // save result to statistic
          // cleanup responseData
        }
    }
}

BotRunner 实体:

public class BotRunner implements Runnable 
{
    private final Bot bot;
    
    public BotRunner(Bot bot) 
    {
        this.bot = bot;
    }
    
    @Override
    public void run() 
    {
       bot.run();
    }
}

尝试以这种方式执行:

//init executor
LocalDateTime termination = LocalDateTime.now().plusSeconds(5L);
while (LocalDateTime.now().isBefore(termination)) 
{
    for (Bot bot : bots) 
    {
        executor.execute(new BotRunner(bot));
    }
}
//shutdown & close executor

更新:

  1. String -> final StringBuffer
    没有帮助。
  2. 使用局部方法变量
    String
    没有帮助。

我希望每个副本都不会引发竞争条件。有人可以问我做错了什么吗?

java concurrency synchronization threadpoolexecutor executor
1个回答
0
投票

您为每个任务使用不同的

mutex
。如果您希望它们互斥地运行,则它们需要锁定同一个实例。

© www.soinside.com 2019 - 2024. All rights reserved.