java中给我们提供了一个Executors类来方便的创建获取一个线程池。有如下几个静态方法用于获取不同类型的线程池:
Executors.newCachedThreadPool();
Executors.newFixedThreadPool(8);
Executors.newScheduledThreadPool(8);
Executors.newSingleThreadExecutor();
Executors.newWorkStealingPool();
通过查看源码我们可以整理出这么一个表格
线程池 | 使用的实现类 |
---|---|
CachedThreadPool | ThreadPoolExecutor |
FixedThreadPool | ThreadPoolExecutor |
ScheduledThreadPool | ScheduledThreadPoolExecutor继承ThreadPoolExecutor |
SingleThreadExecutor | FinalizableDelegatedExecutorService代理ThreadPoolExecutor |
WorkStealingPool(1.8) | ForkJoinPool |
可以看到除了1.8新增的WorkStealingPool以外,其余4个线程池都直接使用或者继承ThreadPoolExecutor类。也就是说虽然通过Executors类获取了不同类型的线程池,但是底层实现都是ThreadPoolExecutor,只是参数或者部分实现不同而已。
ThreadPoolExecutor的创建部分参考:如何创建线程池之ThreadPoolExecutor构造方法参数解析
说一下Executors提供的几个不同类型的线程池的区别:
线程池 | 用途 |
---|---|
CachedThreadPool | 用来创建一个可以无限扩大的线程池,适用于负载较轻的场景,执行短期异步任务。(可以使得任务快速得到执行,因为任务时间执行短,可以很快结束,也不会造成cpu过度切换) |
FixedThreadPool | 创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于负载较重的场景,对当前线程数量进行限制。(保证线程数可控,不会造成线程过多,导致系统负载更为严重) |
ScheduledThreadPool | 适用于执行延时或者周期性任务 |
SingleThreadExecutor | 创建一个单线程的线程池,适用于需要保证顺序执行各个任务 |
WorkStealingPool(1.8) | 并行的线程池,不会保证任务顺序执行,抢占式的工作 |
ps:在阿里巴巴Java开发手册中是禁止使用Executors来创建线程池的。
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
也有一定的道理,所以还是需要懂ThreadPoolExecutor的创建方式,参考如何创建线程池之ThreadPoolExecutor构造方法参数解析
使用请参考:如何提交一个任务到线程池执行?