文章目录
ThreadPoolExecutor执行规则线程回收任务队列拒绝策略
Executors 提供的几种默认线程池自动增长线程池定长线程池任务调度线程池串行线程池串行的任务调度线程池工作窃取线程池
ThreadPoolExecutor
ThreadPoolExecutor threadPoolExecutor
= new ThreadPoolExecutor(
3,
10,
0,
TimeUnit
.MINUTES
,
new SynchronousQueue<>(),
Executors
.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
执行规则
先判断当前线程池的大小是否小于核心线程数,如果小于,则创建线程并执行判断任务队列是否已满,如果没有满,则提交到任务队列中如果任务队列满了,则判断当前线程池大小是否小于最大线程池的大小,如果小于,则创建线程并执行如果当前线程数量已经达到最大值了,则执行拒绝策略
线程回收
需要当前线程池大小 大于 核心线程大小需要线程的空闲时间达到 keepAliveTime 设置的时间如果需要回收核心线程,则需要 allowCoreThreadTimeOut 值为 true,可以通过threadPoolExecutor.allowCoreThreadTimeOut(true); 设置
任务队列
同步移交(直接提交): SynchronousQueue,new SynchronousQueue<>(); 可以看做是一个空队列,里面不会保存任何任务,有界队列:ArrayBlockingQueue,new ArrayBlockingQueue(10); 在创建队列的时候设置队列的初始化容量,大小固定。无界队列:LinkedBlockingQueue,new LinkedBlockingQueue(); 虽然说是无界队列,但是实际上也可以在创建的时候指定最大的大小,如果不指定,默认最大大小就是 Integer.MAX_VALUE。优先级队列:PriorityBlockingQueue,一种特殊的无界队列这个队列将会按照任务的优先级来安排任务的执行顺序,需要插入的任务实现 Comparable 接口,或者在创建时传入Comparable接口实现类,当前优先级大就返回-1,优先级小就返回1,值越小优先级越高。
拒绝策略
AbortPolicy:抛出异常,也是默认的策略DiscardPolicy:直接忽略DiscardOldestPolicy : 丢弃任务队列中最老的任务,也就是最先进来还没有被执行的哪一个,然后再次提交CallerRunsPolicy:直接由提交任务的线程执行该任务
Executors 提供的几种默认线程池
自动增长线程池
Executors
.newCachedThreadPool();
创建一个线程池,线程数最大可达到Integer.MAX_VALUE。将allowCoreThreadTimeOut设置为true后,线程空闲60秒回回收。
public static ExecutorService
newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer
.MAX_VALUE
,
60L
, TimeUnit
.SECONDS
,
new SynchronousQueue<Runnable>());
}
定长线程池
Executors
.newFixedThreadPool(2);
创建一个线程池,在创建时传入线程池大小,当任务达到最大值时将会被加到无界队列中等候
public static ExecutorService
newFixedThreadPool(int nThreads
) {
return new ThreadPoolExecutor(nThreads
, nThreads
,
0L
, TimeUnit
.MILLISECONDS
,
new LinkedBlockingQueue<Runnable>());
}
任务调度线程池
ScheduledExecutorService scheduledExecutorService
= Executors
.newScheduledThreadPool(5);
ScheduledFuture scheduledFuture
= scheduledExecutorService
.schedule(() -> {
System
.out
.println(System
.currentTimeMillis());
}, 10, TimeUnit
.SECONDS
);
scheduledFuture
.cancel(true);
scheduledExecutorService
.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
}
}, 3, 5, TimeUnit
.SECONDS
);
scheduledExecutorService
.scheduleWithFixedDelay(() -> {
}, 10, 5, TimeUnit
.SECONDS
);
如果是周期性的执行任务,当其中一次执行发生异常,后续的任务将不再执行
串行线程池
串行线程池,每次执行一个任务,执行完成之后在执行下一个任务
ExecutorService executorService
= Executors
.newSingleThreadExecutor();
public static ExecutorService
newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L
, TimeUnit
.MILLISECONDS
,
new LinkedBlockingQueue<Runnable>()));
}
串行的任务调度线程池
Executors
.newSingleThreadScheduledExecutor();
工作窃取线程池
这个是Java 1.8 提供的线程池,这种线程池不是扩展自 ThreadPoolExecutor ,实际上是 ForkJoinPool 类。该线程池的线程数量默认为cpu的核心数,任务并行执行,当一个任务执行完成之后就去任务队列中获取新任务继续执行,但是与上面介绍过的先进先出以及优先级队列不同,该线程池执行任务的方式是抢占式的,也就是不能保证任务的执行顺序。
ForkJoinPool forkJoinPool
= (ForkJoinPool
) Executors
.newWorkStealingPool();