线程池 | 构造函数 | ||||
---|---|---|---|---|---|
核心线程 | 最大线程 | 线程存活时间 | 队列 | ||
FixThreadPool | ? | 等于核心线程数 | 永久 | LinkBlockingQuque | |
SingleThreadPool | 1 | 1 | 永久 | LinkBlockingQuque | |
CacheThreadPool | ? | Integer.MAX_VALUE | 60秒 | SynchronousQueue | |
ScheduledThreadPool | ? | Integer.MAX_VALUE | 永久 | DelayedWorkQueue | |
WorkStealingPool | 可用CPU核心数 | 内部类WorkQueue
|
我们在初始化线程池时经常用以下写法(不优雅):
ExecutorService executorService = Executors.newFixedThreadPool(8);
如果该线程池使用场景,task无限多,会造成一个什么问题?
很显然LinkBlockingQueue队列长度我们没有赋值,他会默认Integer.MAX_VALUE,可能会由于队列中待执行任务过多而发生Out_of_Memory
CacheThreadPool与ScheduledThreadPool由于最大线程数为Integer.MAX_VALUE,亦有可能Out_Of_Memory
建议写法:
//创建固定长度线程池、单线程池
ExecutorService executorService = new ThreadPoolExecutor(1,1,0L,
TimeUnit.MICROSECONDS,new LinkedBlockingQueue<>(2));
//创建可变长度线程池
ExecutorService executorService = new ThreadPoolExecutor(0,2,30L,
TimeUnit.DAYS,new SynchronousQueue<Runnable>(true));
//创建延迟(定时)线程池
ExecutorService executorService = new ThreadPoolExecutor(1,5,0L,
TimeUnit.MICROSECONDS,new DelayedWorkQueue<>(5));
//创建workStealing线程池,我更喜欢叫他任务份发线程池
ForkJoinPool forkJoinPool = new ForkJoinPool(7,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,null, true);