ThreadPoolExecutor
addWorker
前面我们看了一下线程池的执行机制。在默认的线程池实现里,它是通过一个workers集合来保持最核心活跃状态的线程组。当我们新加入线程执行任务时,则先利用这里的线程。如果这里的被占用满了之后则加入到workQueue这个队列里排队。这里面有一个重要的地方就是要经常检查当前线程池的状态,只有在运行状态的时候才可以往里面加线程,否则提交线程任务则会被拒绝。我们也要检查线程池的长度,防止提交的执行任务达到了我们设定的上限。为了保证线程的提交和执行安全,我们用一个lock来管理对线程集合workers和workerQueue的加锁控制。
在线程池中也有一些扩展点。比如在线程执行的过程中我们可以覆写beforeExecute, afterExecute方法来提供自己特定的功能。另外,当线程执行不符合条件要被丢弃或者拒绝的时候,我们也可以提供一些RejectExecutionHandler的具体实现。在系统的默认实现里已经提供了5种。
总的来说,对于一个线程池,它最核心的部分是对应一个线程运行集合和一个队列。如果我们能够保证好他们的状态、大小以及线程安全执行,那么基本上一个线程的雏形就差不多完成了。
上面说过,addWorker会用当前task创建一个Worker对象,相当于对task的包装,然后用Worker对象作为task创建一个Thread,该Thread保存在Worker的thread成员变量中。在addWorker中启动了这个线程,线程中执行runWorker方法。
addWorkerFailed
worker
runworker
这个方法要从workQueue里面获取task然后提交执行。也就是说我们线程池执行完了当前的任务后会主动到这个队列里来取后续等待的任务执行。如果当前线程因为超时、线程池要关闭等状态影响则可能会退出,而如果一切都正常的话,则会从workQueue里面调用poll或take方法取到当前任务。前面一大堆的判断和循环就是判断当前线程池长度是否超过maximumPoolSize以及当前状态是否要关闭了。如果长度超了或者状态不对则没必要继续去取任务执行了,需要尽快返回。