Fork me on GitHub

如何安全的创建线程池?

这个问题之所以产生,是来自于阿里的java手册中
【线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式。】
哪个对?个人觉得还是看实际的项目,当你的项目的规模不够大,随便使用都可以,但是如果规模够大,访问量,数据处理,线程的使用量都达到了一定的规模。最好是使用ThreadPoolExecutor,来规避资源耗尽的风险。

简单来说Executors来创建线程池,也是通过调用ThreadPoolExecutor,但是问题在于Executor封装的时候,使用的默认值会带来一些隐患。

首先来看一下,ThreadPoolExecutor的构造函数

/*
corePoolSize,--线程池中保持的线程数量,即使没有被使用,除非设置了线程超时时间

maximumPoolSize,--最大线程数量,当workqueue队列已满,放不下新的任务,在通过execue添加的新的任务则线程池会再创建新的线程,线程数量大于

keepAliveTime,--当线程池中线程数量大于workqueue,如果一个线程空闲时间大于keepalivetime,该线程就会被销毁
unit, --时间单位
workQueue, --阻塞队列,当线程池中正在运行的线程数量达到了corepoolsize,那么通过execute 添加的新任务就会被加到该队列中,在队列中排队执行,
*/

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,Long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory){
this(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,
threadFactory,defaultHandler);
}

由于FixedThreadPool 和SingleThreadExecutor,允许请求的队列长度为integer.MAX_VALUE,所以可能堆积大量的请求,导致OOM。
CachedThreadPool和ScheduledThreadPool,允许创建的线程数量为integer.MAX_VALUE,可能会创建大量线程导致OOM。
所以通过Executors创建的线程池存在风险,建议使用ThreadPoolExecutor创建指定参数的线程池来规避风险。

posted @ 2020-09-02 17:58  WilliamCui  阅读(286)  评论(0编辑  收藏  举报