线程中断-JCIP

时间:2018-06-27 12:04:45

标签: java multithreading

Java Concurrency in Practice第7章第142、143页中,我不太理解2条陈述:

  1. “线程应被其所有者中断”。 -但是,在第141页,扩展Thread的类已暴露 public void cancel() { interrupt(); },其他任何代码都可以调用它!
  2. “只有实现线程中断策略的代码才能吞下中断请求。”

我正在寻找一个清晰,清晰,完整的代码来说明以上两点。

1 个答案:

答案 0 :(得分:1)

JDK本身提供了您要询问的示例:)。看看ThreadPoolExecutor::shutdown

public void shutdown() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        checkShutdownAccess();
        advanceRunState(SHUTDOWN);
        interruptIdleWorkers();
        onShutdown(); // hook for ScheduledThreadPoolExecutor
    } finally {
       mainLock.unlock();
    }
    tryTerminate();
}

1 ThreadPoolExecutor的线程(ThreadPoolExecutor::Worker::thread)仅由ThreadPoolExecutor实例拥有。

ThreadPoolExecutor::shutdown没有公开有关其运行的线程以及如何关闭线程的任何详细信息。它所保证的就是

  

启动有序关闭,其中先前提交的任务位于   执行,但不会接受新任务。

2 当然,您可以为ThreadFactory发出的线程提供覆盖的interrupt方法,如下所示:

public void BadThread extends Thread{
    public BadThread(Runnable r){
        super(r);
    }

    @Override
    public void interrupt(){
        throw new IllegalArgumentException();
    }
}

但这将是一场灾难,因为ThreadPoolExecutor不了解您的中断策略(抛出IllegalArgumentException)。并且根据其实现interruptIdleWorkers方法或runWorker(当发现当前状态为SHUTDOWN,但尚未中断工作程序时)仅在中断工作程序时失败。

因此以下程序 可能 (检索任务和关闭之间存在某些竞争)永远不会终止:

public static void main(String[] args) {
    ThreadFactory tf = BadThread::new;
    ExecutorService es = Executors.newFixedThreadPool(8, tf);
    es.submit(() -> System.out.println("Test"));
    es.submit(() -> System.out.println("Test")); // I added this entry because of
                                                 // shutdown() and runWorker() are 
                                                 // kind of racy and
    es.shutdown();
}