Java 线程中断-JCIP

Java 线程中断-JCIP,java,multithreading,Java,Multithreading,在《实践中的Java并发》(Java Concurrency In Practice)一书第7章第142页和第143页中,我没有完全理解两条语句: “线程应被其所有者中断”。 -然而,在p141上,一个类扩展线程已经公开 public void cancel(){interrupt();}这可以被任何其他代码调用 “只有实现线程中断策略的代码才能接受中断请求。” 我正在寻找一个清晰、清晰、完整的代码来说明上面的两点。您所询问的示例在JDK中提供:)。查看ThreadPoolExecutor::s

在《实践中的Java并发》(Java Concurrency In Practice)一书第7章第142页和第143页中,我没有完全理解两条语句:

  • “线程应被其所有者中断”。 -然而,在p141上,一个类扩展线程已经公开
    public void cancel(){interrupt();}
    这可以被任何其他代码调用
  • “只有实现线程中断策略的代码才能接受中断请求。”

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

    您所询问的示例在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
    )。根据它的实现,
    interruptdleworkers
    方法或
    runWorker
    (当发现当前状态为
    SHUTDOWN
    ,但worker尚未被中断时)在中断worker时简单地失败

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

    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();
    }