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

这篇文章写的挺好的
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();

}

}


回答:

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

以上是 为什么 线程池中正在执行任务的线程 不可以被中断? 的全部内容, 来源链接: utcz.com/p/944376.html

回到顶部