在 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/