private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c); /**如果线程池处于STOP、TIDYING、TERMINATED三种状态之一,或者处于SHUTDOWN状态且阻塞队列为空时,执行decrementWorkerCount(),并返回空任务*/
if (rs >= SHUTDOWN ) {
/**
两种情况:1、关闭状态,此时看队列中是否有任务》return null 2、大于关闭》return null
*/
if(rs >= STOP || workQueue.isEmpty()){
decrementWorkerCount();
return null; //worker就退出了
}
}
int wc = workerCountOf(c);
/**
* 判断当前线程是否允许超时
* 1.设置核心线程允许超时allowCoreThreadTimeOut
* 2.线程池当前线程数超过核心线程数》》》》?????
*/
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
/**
* 判断当前线程是否可以退出
* 第一步 判定当前线程是否符合退出的基本条件
* 1.线程池线程数大于最大线程数 (为了保证线程池数量可控)或者
* 2.当前线程允许超时并且已经超时(为了处理真正超时的线程)
* 符合线程退出的基本条件以后再进行第二步的判断
* 第二步,判定当前的线程池状态,是否可以支持线程退出
* 1,线程池线程数 大于1 (不是最后一个线程就可以直接退出)或者
* 2.线程池任务队列为空(相当于(wc <= 1 && workQueue.isEmpty()) 最后一个线程需要队列为空才可以退出)
* 符合两步的条件的线程,可以正常退出
*/
if ((wc > maximumPoolSize || (timed && timedOut))){
if(wc > 1 || workQueue.isEmpty()){
if (compareAndDecrementWorkerCount(c)){
return null;
}
continue;
}
}
try {
//worker线程会在这里阻塞等待获取任务,如果woker线程允许超时,则阻塞等待一段时间
//不允许超时,则会一直阻塞在这里,直到能获取到任务
//这里会响应中断,一旦线程池关闭,会中断worker线程,等待任务的阻塞状态将被打破
Runnable r = timed ?
//不阻塞 到时间闪人
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
//阻塞
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
网友评论