关于jdk6版本ThreadPoolExecutor中的workerCanExit()方法的一点疑问

veesn 2017-10-11 02:28:25
canExit =
runState >= STOP
|| workQueue.isEmpty()
|| (allowCoreThreadTimeOut && poolSize > Math.max(1, corePoolSize));

上述代码反映,在三种情况下允许当前Worker终止。
我的疑问在第三种情况【 (allowCoreThreadTimeOut && poolSize > Math.max(1, corePoolSize));】
如果allowCoreThreadTimeOut 为false,但是当前线程数poolSize大于核心线程池大小corePoolSize,那么当前工作线程作为workerCanExit()调用之前没有从队列中成功获取到任务的闲置线程,为什么不能终止?
总感觉应改为【poolSize > Math.max(1, corePoolSize))|| allowCoreThreadTimeOut】

想了好久,想不明白。
...全文
203 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39912309 2017-10-11
  • 打赏
  • 举报
回复
你说的那个情况在调用workerCanExit()这个方法之前不是已经判断了吗?
veesn 2017-10-11
  • 打赏
  • 举报
回复
相关的源码在下面,各位路过的大神帮忙分析一下我的疑问吧,谢谢了!

// Worker从队列中获取下一个要执行的任务
Runnable getTask() {
    for (;;) { // 无限循环!
        try {
            int state = runState;
            
            // 1、STOP|TERMINATED态,不处理queue中的任务
            if (state > SHUTDOWN) {
            	return null;
            }

            Runnable r;
            // 2、SHUTDOWN态,线程池不会再接收新任务,也就是说不会有新任务添加到队列中,所以选不阻塞的poll()!
            if (state == SHUTDOWN) { 
            	r = workQueue.poll(); 
            }
            
            // 3、RUNNING态
            // 3.1、如果  (poolSize > corePoolSize) || 允许核心线程超时;
            // XXX 当前工作线程可能不能马上获取到任务,需要用带超时的poll方法实现keepAliveTime的超时终止机制
            else if (poolSize > corePoolSize || allowCoreThreadTimeOut) {
            	r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS); 
            }
            // 3.2、否则  (poolSize <= corePoolSize) && 不允许核心线程超时;
            // 这种情况当前工作线程就是核心线程,且不允许被终止,所以调用阻塞的take方法! 
            else { 
            	r = workQueue.take();
            }
            
            if (r != null){
				return r;
            }
            
            // 如果代码走的是2或3.1这两个poll相关的执行路径中的一个,且没有获取到任务,则再检测一下是否可以终止当前工作线程。 
            if (workerCanExit()) {
            	// 如果经判断可以终止当前Worker,那么在终止当前Worker前,若线程池状态为已关闭,则可中断其它所有闲置的Worker。
                if (runState >= SHUTDOWN) { 
                	interruptIdleWorkers(); 
                }
                // 通过返回null终止当前Worker
                return null; 
            }
            // 如果经判断不能终止当前Worker,则继续下次循环再次尝试获取任务!
            
        } catch (InterruptedException ie) {
            // On interruption, re-check runState
        }
    }
}
/**
 * 出现下面三种情况即可终止:
 * 1、如果pool的状态为 STOP|TERMINATED
 * 2、队列为空
 * 3、允许回收核心线程 并且 当前线程数大于核心线程池大小
 */
private boolean workerCanExit() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    boolean canExit;
    try {
		canExit = runState >= STOP || workQueue.isEmpty()
				|| (allowCoreThreadTimeOut && poolSize > Math.max(1, corePoolSize)); // XXX ???
    } finally {
        mainLock.unlock();
    }
    return canExit;
}
veesn 2017-10-11
  • 打赏
  • 举报
回复
引用 2 楼 qq_39912309 的回复:
如果allowCoreThreadTimeOut 为false,在&&条件下根本不会判断后面的条件
我的意思是当allowCoreThreadTimeOut 为false时也存在需要中断当前Worker的情况, 而源代码体现的意思是如果allowCoreThreadTimeOut 为false,就一定不可中断当前Worker。 麻烦再看看,谢谢,想不通。
qq_39912309 2017-10-11
  • 打赏
  • 举报
回复
如果allowCoreThreadTimeOut 为false,在&&条件下根本不会判断后面的条件
veesn 2017-10-11
  • 打赏
  • 举报
回复
求来人啊,来人呀

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧