为什么 线程池中正在执行任务的线程 不可以被中断?

这篇文章写的挺好的
https://juejin.cn/post/684490...

其中 Worker的runWorker方法中 在执行任务之前使用了 lock方法获取锁,任务执行结束之后再释放锁。这个锁的主要作用就是 避免线程池关闭线程时对正在执行任务的线程进行中断操作。

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    //获取第一个任务
    Runnable task = w.firstTask;
    w.firstTask = null;
    //允许中断
    w.unlock();
    //是否因异常退出循环
    boolean completedAbruptly = true;
    try {
        //如果task为空,则通过getTask来获取任务
        while (task != null || (task = getTask()) != null) {
            w.lock();
            /**
             * 如果线程池正在停止,那么要保证当前线程时中断状态;
             * 如果不是的话,则要保证当前线程不是中断状态
             */
            if ((runStateAtLeast(ctl.get(), STOP) ||
                    (Thread.interrupted() &&
                            runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                wt.interrupt();
            try {
                //beforeExecute和afterExecute是留给子类来实现的
                beforeExecute(wt, task);
                Throwable thrown = null;
                try {
                    //通过任务方式执行,不是线程方式
                    task.run();
                } catch (RuntimeException x) {
                    thrown = x;
                    throw x;
                } catch (Error x) {
                    thrown = x;
                    throw x;
                } catch (Throwable x) {
                    thrown = x;
                    throw new Error(x);
                } finally {
                    afterExecute(task, thrown);
                }
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        //processWorkerExit会对completedAbruptly进行判断,表示在执行过程中是否出现异常
        processWorkerExit(w, completedAbruptly);
    }
}

基于以上内容有两个问题:
(1) 如果一个线程 正在运行,他不会主动检查线程的中断状态, 也不会执行能够抛出中断异常的阻塞方法, 那么 其他线程对这个线程发起中断 ,这个被中断的线程 应该感知不到 也不会退出线程,中断是一种协作机制,其他线程发起中断如果我不主动检测是感知不到中断,也不会退出线程。 我的这个理解是否正确?

(2)为什么线程池中的线程 在执行任务的时候 要避免 这个线程被中断?

按照我的理解,基于第一点的原因,我觉的 正在执行任务的线程允许中断也无妨,因为从源码的内容来看,线程能否响应这个中断 取决于 用户的任务 task的run方法中是否 存在对中断的主动检查 以及是否会执行能够抛出中断异常的方法。

补充内容:

    /**
     * Interrupts threads that might be waiting for tasks (as
     * indicated by not being locked) so they can check for
     * termination or configuration changes. Ignores
     * SecurityExceptions (in which case some threads may remain
     * uninterrupted).
     *
     * @param onlyOne If true, interrupt at most one worker. This is
     * called only from tryTerminate when termination is otherwise
     * enabled but there are still other workers.  In this case, at
     * most one waiting worker is interrupted to propagate shutdown
     * signals in case all threads are currently waiting.
     * Interrupting any arbitrary thread ensures that newly arriving
     * workers since shutdown began will also eventually exit.
     * To guarantee eventual termination, it suffices to always
     * interrupt only one idle worker, but shutdown() interrupts all
     * idle workers so that redundant workers exit promptly, not
     * waiting for a straggler task to finish.
     */
    private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                   //这个地方 w.tryLock 检测 woker的锁是否已经处于locked状态
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }
阅读 3k
1 个回答

(1) 中断是可以被响应的,比如sleep,lock 的 一些方法等。其余的则需要自己自己主动检测响应。
(2) 我考虑了下,我觉得很有可能是怕影响同线程的其他任务,如果在运行过程中不清楚,由同一个线程执行的其他任务中,一旦在开头执行中断检测,就莫名其妙的退出了任务。毕竟核心线程就那么多,某一个任务中的中断,可能随机影响其他许许多多的任务。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题