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】想了好久,想不明白。

解决方案 »

  1.   

    如果allowCoreThreadTimeOut 为false,在&&条件下根本不会判断后面的条件
      

  2.   


    我的意思是当allowCoreThreadTimeOut 为false时也存在需要中断当前Worker的情况,
    而源代码体现的意思是如果allowCoreThreadTimeOut 为false,就一定不可中断当前Worker。
    麻烦再看看,谢谢,想不通。
      

  3.   

    相关的源码在下面,各位路过的大神帮忙分析一下我的疑问吧,谢谢了!// 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;
    }
      

  4.   

    你说的那个情况在调用workerCanExit()这个方法之前不是已经判断了吗?