概述
ThreadPoolExecutor
是Java
中最基本的线程池实现,Executors类的工厂方法newFixedThreadPool()
、newCachedThreadPool()
、newSingleThreadPool()
等,内部都是用ThreadPoolExecutor
实现的。
内部类Worker
线程池中实际执行任务的基本工作单元。
基本成员
Thread thread
:供Worker
运行的线程,也即线程池的工作线程。Runnable firstTask
:初始化Worker
类时传入的Runnable
对象。
构造Worker
对象时,需要传入firstTask
,也就是这个Worker
将要运行的第一个Runnable
。同时构造函数中会为Worker
生成一个新的线程。
工作循环
线程池比一般的线程高级的地方在于,它实现了线程复用,同一个线程执行完一个任务后可以继续执行下一个任务,而一般的线程在执行完后就废弃了,因为Thread.start()
方法只能调用一次。
线程池中的线程复用是由工作循环实现的,Worker
类实现了Runnable
接口,它的run()
方法就是一个无限循环,负责不断地获得并执行任务。
因为构造Worker
类时传入了firstTask
,所以第一次循环会执行firstTask
,此后的循环,则会从workerQueue
中取出Runnable
执行。
线程管理
与线程管理有关的属性:
int corePoolSize
:核心线程数int maxPoolSize
:最大线程数BlockingQueue workerQueue
:等待队列
线程产生
当调用ThreadPoolExecutor.execute(Runnable runnable)
方法提交新任务时,会按照以下步骤处理:
- 如果现有线程数量小于
corePoolSize
,则新建一个Worker
对象,传入的Runnable
即为该Worker
的firstTask
,并使得Worker
对于的Thread
开始运行。 - 如果该
Runnable
可以放入workerQueue
,则放入workerQueue
。 - 如果
workerQueue
已满,则判断当前线程数是否小于maxPoolSize
,若满足,则新建一个Worker
对象运行传入的Runnable
,若不满足,则reject
该Runnable
。
线程销毁
当某个Worker
执行完一个Runnable
,从workerQueue
中获取新任务时,如果在给定的阻塞时间内获取不到任务,且当前线程数量大于corePoolSize
,则该Worker
关闭。通俗的说,只有当任务很多时,线程数量才会超过corePoolSize
,比较空闲的时候,线程数量会保持在corePoolSize
。