最近公司里要求使用ecplise上的阿里代码扫描插件来扫描代码,自己装上后看了下,问题还挺多的。其中Blocker的大多数都明白,只是有一条报错很有疑惑:1Executors.newFixedThreadPool(nThreads)
这是我创建线程池常用的方法,设置线程池了的上限,难道有什么问题吗?
看了一下详细信息:
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
纳尼,还让我自己手动去创建,有点高大上啊。
说明:Executors各个方法的弊端:
- newFixedThreadPool和newSingleThreadExecutor:
- 主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM(out of memory)。
- newCachedThreadPool和newScheduledThreadPool:
- 主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。
看一下阿里给的example:
|
|
在Spring中的配置
|
|
ThreadPoolExecutor
|
|
构造方法参数讲解
参数名 | 作用 |
---|---|
corePoolSize | 核心线程池大小 |
maximumPoolSize | 最大线程池大小 |
keepAliveTime | 线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使得核心线程有效时间 |
TimeUnit | keepAliveTime时间单位 |
workQueue | 阻塞任务队列 |
threadFactory | 新建线程工厂 |
RejectedExecutionHandler | 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理 |
线程创建策略:
- 当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
- 当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
- 当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
- 当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
- 当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
- 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭
拒绝策略:
- ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
- ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
- ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
- ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
总结
|
|