2019-05-04 线程池ThreadPoolExecutor
1.线程池参数详解
在上一篇文章java常用线程池中,可以看到它们都使用了一个核心的线程池类ThreadPoolExecutor,它有好几个参数,下面来看下各个参数代表什么意思:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
1.corePoolSize 核心池大小。
- 活动线程小于corePoolSize的时候创建新的线程;
- 活动线程大于corePoolSize时都是先加入到任务队列workQueue当中;
- 任务队列满了再去启动新的线程,如果线程数达到最大值就拒绝任务;
2.maximumPoolSize 最大线程数,线程池里面的最大线程数。当超过这个数,就会去执行拒绝策略RejectedExecutionHandler 。
3.keepAliveTime 空闲线程存活时间。大于corePoolSize,并且任务队列满了后,创建的线程的空闲存活时间,当超过了这个时间,后面创建的线程就会关闭。
4.unit 空闲存活时间keepAliveTime 的时间单位,包括
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
5.threadFactory 线程工程主要用来创建线程。
6.workQueue 存放缓存的任务,可供选择的阻塞队列有以下几种:
- ArrayBlockingQueue是一个有边界的阻塞队列,它的内部实现是一个数组。它的容量在初始化时就确定不变。
- LinkedBlockingQueue:阻塞队列大小的配置是可选的,其内部实现是一个链表(SingleThreadPool、FixedThreadPool)。
- PriorityBlockingQueue:是一个没有边界的队列,所有插入到PriorityBlockingQueue的对象必须实现java.lang.Comparable接口,队列优先级的排序就是按照我们对这个接口的实现来定义的。
- SynchronousQueue队列内部仅允许容纳一个元素。当一个线程插入一个元素后会被阻塞,除非这个元素被另一个线程消费(CachedThreadPool)。
- DelayedWorkQueue 定时的以及周期性的执行任务(ScheduledThreadPool)。
7.handler 表示当拒绝处理任务时的策略,有以下四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
说明:线程池创建的时候,默认里面的线程数0。当有一个任务提交的时候,当前线程池中的线程数小于corePoolSize时,就创建一个新的线程来执行任务。如果此时的线程池的线程数大于corePoolSize,并且任务队列workQueue还没满,就把任务放到workQueue中,等待正在执行的线程执行完,再取出任务执行。如果任务队列满了,线程池中的线程数小于maximumPoolSize,那么就会创建一个线程来执行任务。如果线程池中的线程数已经等于maximumPoolSize了,再创建新的线程就超了,于是就会执行拒绝的策略RejectedExecutionHandler 。
2.线程池状态
在ThreadPoolExecutor中定义了一个volatile变量,另外定义了几个static final变量表示线程池的各个状态:
volatile int runState;
static final int RUNNING = 0;
static final int SHUTDOWN = 1;
static final int STOP = 2;
static final int TERMINATED = 3;
runState表示当前线程池的状态,它是一个volatile变量用来保证线程之间的可见性;
- 当创建线程池后,初始时,线程池处于RUNNING状态;
- 如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕;
- 如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,会去尝试终止正在执行的任务,并且清空任务缓存队列,并返回未执行的任务;
- 当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态。