【发布时间】:2021-09-29 11:21:20
【问题描述】:
我有一堆任务要并行执行。任务分为阶段,每个阶段的任务取决于前一阶段任务的结果。因此,一个阶段上的所有任务必须在递归地进入下一个阶段之前完成执行。代码如下:
java.util.concurrent.Executor executor;
void process(Stage stage) throws InterruptedException {
Task[] tasks = stage.tasks();
CountDownLatch countDownLatch = new CountDownLatch(tasks.length);
logger.info("Execute {} tasks on stage {}", tasks.length, stage.index());
for (Task task : tasks) {
executor.execute(() -> {
this.execute(task);
countDownLatch.countDown();
});
}
countDownLatch.await(); // Wait for all tasks to finish
if (! stage.isLast()) {
process(stage.next()); // Execute tasks on the next stage
}
}
到目前为止,一切正常。但是,我不想记录每个阶段的进度,而是定期在单独的TimerTask:
class Progress extends TimerTask {
@Override
public void run() {
logger.info("Executed {}/{} tasks on stage {}/{}",
executedTasksOnStage, totalTasksOnStage, currentStageIndex, totalStageCount);
}
}
如何以线程安全的方式将上面记录的变量从process() 方法传递给Progress 对象?我熟悉简单的原子计数器,但在这种情况下,有多个变量一起更新,然后再单独更新。这也是一个设计问题,如果您能提供代码示例,我将不胜感激。
【问题讨论】:
-
有什么理由不在舞台上积累统计数据等?这似乎是维护您的状态信息的自然场所。一个更高的概念,管道,可以跟踪它处于哪个阶段。然后报告可以简单地查询管道和阶段的执行细节。
-
感谢您的意见!我将发布我的解决方案作为答案。
标签: java concurrency timertask