每一个任务:Runnable只有两种处理方式
1、创建Worker执行;
2、进入阻塞队列。
每一个Worker中获取Runnable的方式只有两种方式
1、第一个进来的Runnable对象,也就是创建Worker的那个,会被Worker执行;
2、从阻塞队列中take取出Runnable对象。
注意⚠️:Worker并不会在等待过程中处理非第一个Runnable对象,也就是说旧Worker不会执行新进来的Runnable对象,除非他来自阻塞队列。
跟核心线程数的比对、最大线程数、阻塞队列的比对,处理情景
当核心线程数为4、最大线程数为10、阻塞队列最大长度为20
此时如果有Runnable【线程任务】进来,则会判断workerCount【Worker的数量】、maxThreadCount【最大线程数】和阻塞队列大小。进行具体分析在做操作。
- 如果workerCount < coreThreadCount【核心线程数】,则创建新的Worker执行Runnable对象;
- 如果workerCount = coreThreadCount,则新进来的Runnable对象进入阻塞队列中,等待其他的Worker中的Runnable对象执行完毕,再被其他Worker采用阻塞队列的take方法获取到并执行;
- 如果workerCount < maxThreadCount并且BlockingQueue【阻塞队列满了】,此时新进来的Runnable对象将重新创建Worker执行Runnable。(也就是说,此时新进来的比之前进来的Runnable可能早执行,因为之前的处在阻塞队列中被阻塞,还在等待状态)。
- 如果workerCount = maxThreadCount并且BlockingQueue【阻塞队列满了】,则通过拒绝策略拒绝任务。我干不动了!
经典提问
1、如果此时上述条件成立,一共有8个任务,怎么为其分配线程?
答案:分配核心线程数4个,其他后续任务进入阻塞队列。
2、线程池中先来到的任务,一定比后来到的任务执行完早嘛?
答案:不一定,如果workerCount < coreThreadCount,则早来早执行;如果workerCount = coreThreadCount并且阻塞队列未满,则早来早执行,如果此时阻塞队列满了,则后来的任务会先执行。