Executors静态工厂方法(gold_axe)
2020-10-24 本文已影响0人
胖达_4b7e
里面包ThreadPoolExecutor 的都不建议使用:
主要是因为
要么 无限队列 : newSingleThreadExecutor,newFixedThreadPool
要么 无限线程 : newFixedThreadPool,newScheduledThreadPool
会OOM
可以方便的创建一些预配置的线程池,主要方法有:
newSingleThreadExecutor
:始终一个线程,所有任务排队进行,无限队列!:
public static ExecutorService newSingleThreadExecutor() {
return new ThreadPoolExecutor(1, 1,//始终一个线程
0L, TimeUnit.MILLISECONDS,//就一个线程,永不回收
new LinkedBlockingQueue<Runnable>());//无限排队
}
该线程池适用于需要确保所有任务被顺序执行的场合。
newFixedThreadPool
固定线程,永不回收,无限长的排队(死锁就是它):
用于已经知道有多大并发压力的, 可以确定线程数的
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,//固定线程数
0L, TimeUnit.MILLISECONDS,//永不超时
new LinkedBlockingQueue<Runnable>());//无界队列
}
如果排队任务过多,可能会消耗非常大的内存。
newCachedThreadPool
无固定线程数.不用排队,线程空闲60秒就回收:
适合 任务执行时间短的
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0,
Integer.MAX_VALUE,//几乎无上限的线程数
60L, TimeUnit.SECONDS,//空闲60秒超时
new SynchronousQueue<Runnable>());//无等待队列
}
会创建太多线程的高负荷情况下, 太多竞争CPU和内存资源,不宜使用
一般情况,任务可以不经排队,直接交给某一个空闲线程 效率比newFixedThreadPool
高
newScheduledThreadPool
定时任务, 无限线程, 只有一个线程
newWorkStealingPool
适合大任务分解并行执行, 基于ForkJoinPool, 工作窃取的算法 把任务分解成无关的子任务