概述
线程池不应使用Executors去创建,而是通过ThreadPoolExecutor的方式。这样的处理方式让写的同学更加明确线程池的运行规则。规避资源耗尽的风险。
executors创建线程池
- Executors.newFixedThreadPool()
创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化。虽然线程数量是固定的,但是阻塞队列是无界队列。如果有很多请求积压,阻塞队列越来越长,容易导致OOM。
(无界队列其实是用了默认参数Integer.MAX_VALUE,一般来说,不应该允许那么多请求等待)
- Executors.newCachedThreadPool()
创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时, 它可以灵活的添加新的线程,而不会对池的长度作任何限制无核心线程
(线程数量不固,和newFixedThreadPool一样请求一多,容易OOM)
- Executors.newScheduledThreadPool()
创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer
(和newFixedThreadPool类似,支持定时和周期性任务执行,也是无界队列,容易导致OOM)
- Executors.newSingleThreadExecutor()
创建一个单线程化的executor,它只创建唯一的worker线程来执行任务,必须前一项任务执行完毕才能执行后一项。
(核心线程和非核心线程的区别,没有区别,所谓核心线程是指线程不被销毁的数值范围,而哪些线程被销毁是随机的)
概括:
高并发情况无界队列会有OOM的风险,所以推荐做法是使用ThreadPoolExecutor(定时和周期性任务使用ScheduledThreadPoolExecutor)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
创建一个新的 ThreadPoolExecutor
与给定的初始参数和默认线程工厂和拒绝执行处理程序。
corePoolSize 核心线程数量
maximumPoolSize 最大线程数量
keepAliveTime 线程保持时间,N个时间单位
unit 时间单位(比如秒,分)
workQueue 阻塞队列
threadFactory 线程工厂
handler 线程池拒绝策略
最后
以上就是粗心冬天为你收集整理的Executors和ThreadPoolExecutor那种方式创建线程池更好的全部内容,希望文章能够帮你解决Executors和ThreadPoolExecutor那种方式创建线程池更好所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复