Executors提供四种线程池:
newCachedThreadPool :缓存线程池,如果线程池长度超过处理需要,可回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool : 定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool : 计划线程池,支持定时及周期性任务执行。
newSingleThreadExecutor :单线程线程池,用唯一的线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
ThreadPoolExecutor有几个重要的成员变量:keepAliveTime、allowCoreThreadTimeOut、poolSize、corePoolSize、maximumPoolSize。下面分别介绍一下:
corePoolSize:线程池的基本大小。下面会解释什么是基本大小。
maximumPoolSize:线程池中允许的最大线程数。
注意还有一个largestPoolSize,记录了曾经出现的最大线程个数。因为setMaximumPoolSize()可以改变最大线程数。
poolSize:线程池中当前线程的数量。
那么poolSize、corePoolSize、maximumPoolSize三者的关系是如何的呢?
当新提交一个任务时:
(1)如果poolSize<corePoolSize,新增加一个线程处理新的任务。
(2)如果poolSize=corePoolSize,新任务会被放入阻塞队列等待。
(3)如果阻塞队列的容量达到上限,且这时poolSize<maximumPoolSize,新增线程来处理任务。
(4)如果阻塞队列满了,且poolSize=maximumPoolSize,那么线程池已经达到极限,会根据饱和策略RejectedExecutionHandler拒绝新的任务。
// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
submit
,同步提交返回一个Futureexecute
,同步提交,返回voidshutdown
,设置线程池状态为shutdown,并且worker全部中断(非运行状态尝试),返回值voidshutdownNow
,设置线程池状态为stop,并且流走当前运行在线程,返回List通过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可以使用
getTaskCount
:线程池已经执行的和未执行的任务总数;
getCompletedTaskCount
:线程池已完成的任务数量,该值小于等于taskCount;
getLargestPoolSize
:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过,也就是达到了maximumPoolSize;
getPoolSize
:线程池当前的线程数量;
getActiveCount
:当前线程池中正在执行任务的线程数量。
通过这些方法,可以对线程池进行监控,在ThreadPoolExecutor类中提供了几个空方法,如beforeExecute方法,afterExecute方法和terminated方法,可以扩展这些方法在执行前或执行后增加一些新的操作,例如统计线程池的执行任务的时间等,可以继承自ThreadPoolExecutor来进行扩展。