线程池解析

线程池


1.ThreadPoolExecutor

1.线程池参数

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {

corePoolSize:核心线程数

maximumPoolSize:maximumPoolSize – the maximum number of threads to allow in the pool

​ 非核心线程数=maximumPoolSize - 核心线程数

keepAliveTime: 时间

unit :时间单位 非核心线程会有存活时间,到时间会自动销毁,比如有定时任务删除未支付订单,大促时会增加非核心线程处理未处理订单

workQueue:队列 处理任务太多排队,线程处理完从队列里取任务

threadFactory:线程工厂,线程从线程工厂创建

handler:拒绝策略,队列排满了就会拒绝掉

newCachedThreadPool

会让CPU100%,因为最多创建线程Integer.MAX_VALUE (0x7fffffff) 2的31次方-1

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
newFixedThreadPool

每次最多固定线程执行,任务放到队列中,可能会内存溢出

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
newSingleThreadExecutor

任务放到队列中,可能会内存溢出

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

2.线程池执行流程

线程池流程图

线程优先级

提交优先级

  1. 先提交核心线程
  2. 再提交等待队列
  3. 最后提交非核心线程

执行优先级:先执行已经有的任务,最后执行等待队列里的任务

  1. 先执行核心线程任务
  2. 再执行非核心线程任务
  3. 最后执行队列里的任务

ThreadPoolExecutor.java源码1127行

while (task != null || (task = getTask()) != null) {

getTask()是从队列里取

在这里插入图片描述

拒绝策略场景分析

(1)AbortPolicy
AbortPolicy

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

这是线程池默认的拒绝策略,在任务不能再提交的时候,抛出异常,及时反馈程序运行状态。如果是比较关键的业务,推荐使用此拒绝策略,这样子在系统不能承载更大的并发量的时候,能够及时的通过异常发现。

(2)DiscardPolicy

ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。

使用此策略,可能会使我们无法发现系统的异常状态。建议是一些无关紧要的业务采用此策略。例如,本人的博客网站统计阅读量就是采用的这种拒绝策略。

(3)DiscardOldestPolicy

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。

此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量。

(4)CallerRunsPolicy

ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

如果任务被拒绝了,则由调用线程(提交任务的线程)直接执行此任务,我们可以通过代码来验证这一点:

public static class CallerRunsPolicy implements RejectedExecutionHandler {
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

如果线程池已经被关闭,则直接丢弃该任务。r.run()(.run只是普通调方法) 是调用者所在线程来运行任务。

(5)通过实现 RejectedExecutionHandler 接口自定义拒绝策略

关注公账号获取插件地址

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值