Java线程池
控制线程数量,处理过程中将任务放入队列,然后线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,在从队列中取出任务来执行。
特点:线程复用,控制最大并发数,管理线程
使用线程池的好处是,减少在创建和销毁线程上所消耗的时间以及系统的资源开销,解决资源不足的问题。
1.优点
- 降低资源消耗
- 提高响应速度
- 提高线程的可管理性
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
}
corePoolSize: 核心线程数,
核心线程会一直存活,即使没有任务需要执行
当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
设置allowCoreThreadTimeout=true,核心线程会超时关闭,默认是false
核心线程
CPU密集型:核心线程数=CPU核心数(或 核心线程数=CPU核心数+1)
I/O密集型:核心线程数=2*CPU核心数(或 核心线程数=CPU核心数/(1-阻塞系数))
混合型:核心线程数=(线程等待时间/线程CPU时间+1)*CPU核心数
maximumPoolSize 最大线程数
当线程数大于等于corePoolSize,且任务队列已满时,线程池会创建新线程来处理任务.
当线程数等于maxPoolSize,且任务队列已满时,线程池会采用拒绝策略处理任务.
IO密集型经验应用,最大线程设置为 2N+1 (N为CPU数量,下同).
CPU密集型应用,最大线程设置为 N+1.
keepAliveTime 线程空闲时间
unit keepAliveTime 的单位
workQueue 任务队列
被提交但尚未被执行的任务,任务队列需要设置边界
否则可能会因为产生任务过多,工作线程处理不及时导致任务全部堆积在队列中,从而OOM
threadFactory:线程工厂 用于创建线程,一般用默认的即可。
handler:拒绝策略
当任务太多来不及处理,如何拒绝任务。
● AbortPolicy:直接抛出异常,阻止系统正常运行。
● CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是极有可能会导致调用者线程的性能会急剧下降。
● DiscardOldestPolicy : 丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
● DiscardPolicy : 该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢失,这是最好的策略。