首页 > 解决方案 > Java 并发实践“清单 7.21. ExecutorService 在关机后跟踪取消的任务。”。比赛条件在哪里?

问题描述

我正在阅读Java Concurrency in Practice并遇到以下代码片段。

public class TrackingExecutor extends AbstractExecutorService {
    private final ExecutorService exec;
    private final Set<Runnable> tasksCancelledAtShutdown =
            Collections.synchronizedSet(new HashSet<Runnable>());
    ...
    public List<Runnable> getCancelledTasks() {
        if (!exec.isTerminated())
            throw new IllegalStateException(...);
        return new ArrayList<Runnable>(tasksCancelledAtShutdown);
    }

    public void execute(final Runnable runnable) {
        exec.execute(new Runnable() {
            public void run() {
                try {
                    runnable.run();
                } finally {
                    if (isShutdown()
                            && Thread.currentThread().isInterrupted())
                        tasksCancelledAtShutdown.add(runnable);
                }
            }
        });
    }

    // delegate other ExecutorService methods to exec
}

书上说:

TrackingExecutor 有一个不可避免的竞争条件,可能会导致误报:被标识为已取消但实际上已完成的任务。这是因为线程池可能在任务的最后一条指令执行和池将任务记录为完成之间关闭。

是指下面的情况吗?

  1. 一个工作线程已完成,但在块runnable.run()处停止。finally
  2. exec已关闭。
  3. 工作线程执行finally块并添加runnabletasksCancelledAtShutdown. (runnable.run()已完结,应该认作finished,不是cancelledAtShutdown

我做对了吗?如果不是,竞争条件在哪里?“线程池可以在任务的最后一条指令执行和池将任务记录为完成之间关闭”的真正含义是什么?

标签: javamultithreading

解决方案


推荐阅读