工作流程
多线程注意点
1)线程池是如何保证线程不被销毁的呢?
2)那么线程池中的线程会处于什么状态?
3)核心线程与非核心线程有区别吗?
1)线程池是如何保证线程不被销毁的呢?
答案:如果队列中没有任务时,核心线程会一直阻塞在获取任务的方法,直到返回任务。而任务执行完后,又会进 入下一轮 work.runWork()中循环,runwork() —>getTask(),获取之前判断当前线程数是否大于coreSize,分别执行阻塞获取take()和poll方法超时销毁
验证:秘密就藏在核心源码里
//work.runWork():
while (task != null || (task = getTask()) != null)
//work.getTask():
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take()
2)那么线程池中的线程会处于什么状态?
答案:RUNNABLE,WAITING 验证:起一个线程池,放置一个任务sleep,debug查看结束前后的状态
3)核心线程与非核心线程有区别吗?
答案:没有。被销毁的线程和创建的先后无关。即便是第一个被创建的核心线程,仍然有可能被销毁
验证:看源码,每个works在runWork的时候去getTask,在getTask内部,并没有针对性的区分当前work是否是核 心线程或者类似的标记。只要判断works数量超出core,就会调用poll(),否则take()
// Are workers subject to culling? ‐ 很形象,要不要乖乖的被“捕杀”?
//判断是不是要超时处理,重点!!!决定了当前线程要不要被释放
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
try {
//重点!!!
//如果线程可被释放,那就poll,释放的时间为:keepAliveTime
//否则,线程是不会被释放的,take一直被阻塞在这里,知道来了新任务继续工作
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
//到这里说明可被释放的线程等待超时,已经销毁,设置该标记,下次循环将线程数减少
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}