ThreadPoolExecutor
有如下几个参数:
corePoolSize: 核心线程数量
maximumPoolSize: 线程最大线程数
workQueue: 阻塞队列,存储等待执行的任务,很重要,会对线程池运行过程产生重大影响
keepAliveTime: 线程没有任务执行时最多保持多久时间终止
threadFactory: 线程工厂,用来创建工厂(默认情况下,会有一个默认的工厂创建)
corePoolSize,maximumPoolSize,workQueue参数之间的关系:
1.如果运行的线程数小于corePoolSize的时候,直接创建新的线程来处理任务,即使线程池中其他线程是空闲的。
2.如果线程池中的线程数量大于等于corePoolSize,且小于maximumPoolSize的时候,则只有当workQueue满的时候,才创建新的线程,去处理任务。
3.如果设置的corePoolSize和maximumPoolSize相同的话,那么创建的线程池大小是固定的,这个时候有新任务提交,workQueue没有满的时候,就把请求放到workQueue里面,等待有空闲的线程从这里面取出任务进行处理。
4.如果我们运行的线程数量大于maximumPoolSize,这时workQueue也已经满了,那么就需要使用拒绝策略处理这个任务。
核心线程数量和线程最大线程数的关系处理
1.减低系统资源的消耗,包括CPU的使用率,操作系统资源的消耗,可以设置较大的队列容量和较小的线程池容量,这样会降低线程处理任务的吞吐量。
2.提交的任务经常发生阻塞,调用设置线程最大线程数方法,重新设定线程池的容量。
3.如果队列的容量设置较小,通常需要把这个线程池容量设置大一点,这样CPU的使用率会相对应的高一些,但是线程池的容量设置的过大,在提交任务过多的情况下,并发量会增加,那么线程之间的调度就是需要考虑的问题,这样反而会降低任务的吞吐量。
还有一个参数:rejectHandle:拒绝处理任务的策略,有4种策略
1.直接抛出异常(默认的策略)
2.用调用所在的线程调用任务
3.丢弃队列中最靠前的任务,并执行当前任务
4.直接丢弃当前任务