在 Brian Goetz 等人的 Java Concurrency in Practice 一书中,第 141 页(2006)中的示例:


class PrimeProducer extends Thread {
}
...
public void cancel() { interrupt(); }

令人困惑的是,书中指出线程应该实现中断策略,而 Runnable/Callable 任务应该实现取消策略。

然而,我们在 Thread 对象中使用了 cancel() 方法。 那是怎么回事?几页之前,给出了带有 cancel() 的 Runnable 示例(7.1)。在任务的情况下,我希望看到这样的合格 interrupt():
public void cancel() { Thread.currentThread().interrupt(); }

额外的、半相关的信息

我正在使用 ExecutorService,所以我处理任务(不是线程——除了 ExecutorService 的线程工厂),但我在书中找不到任何完整的 ExecutorService 关闭(许多线程)的示例。

我启动和停止任务的方法是:
Map<CancellableRunnable, Future<?>> cancellableFutures = new HashMap<>(); // keep track of refs to tasks for stop()
public void init() {
  Future<?> future = myExecutorService.submit(myTask);
  cancellableFutures.put(myTask, future);
}

public void stop() {
  for (Future task : cancellableFutures.values()) {
    task.cancel(true); // also a confusing step. Should it be cancel() on Future or cancel() on task (Runnable/Callable)?
  }
}

最佳答案



正确的,

class MyThread extends Thread {
    @Override
    public void interrupt() { ... }
}



正确的,
// FutureTask = Runnable (for run) + Future<Void> (for cancel(boolean))
class MyTask extends FutureTask<Void> {
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) { ... }

    @Override
    public void run() { ... }
}


Thread 既是 Thread 又是 Runnable ,所以应该定义 interrupt(中断这个线程)和 cancel(取消这个任务,这个线程当前正在运行的任务)。
public class Thread implements Runnable { ... }
PrimeProducer 示例有点令人困惑,因为它假定 PrimeProducer 中定义的任务将在 PrimeProducer 之外使用。
class PrimeProducer extends Thread {

    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!Thread.currentThread().isInterrupted())
                queue.put(p = p.nextProbablePrime());
        } catch (InterruptedException consumed) {
            /* Allow thread to exit */
        }
    }

    public void cancel() { interrupt(); }

}

这是非常合理和准确的,因为我们可以做到
Runnable runnable = new PrimeProducer();
new Thread(runnable).start();

不过,这种情况很少见。我们很可能只会选择
new PrimeProducer().start();

这将使我们在 run 上下文感知和 Thread.currentThread().isInterrupted()isInterrupted() 中定义的任务含义相同。这就是你对 Thread.currentThread().interrupt()interrupt() 的困惑的来源。

关于java - Java Concurrency in Practice 中的 "Using interruption for cancellation"是否有拼写错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57769016/

10-15 06:11