ThreadPoolExecutor的七大参数及工作原理

目录

一、线程池的重要参数

          二、线程池工作原理


一、线程池的重要参数

线程池:ThreadPoolExecutor 的 API、源码

源码:

public ThreadPoolExecutor(    int corePoolSize,		//核心线程池大小 (今日当值窗口
                              int maximumPoolSize,	//最大线程池大小  (扩容窗口最大
                              long keepAliveTime,	//超时时间,超时时间过后未使用的线程会被释放
                              TimeUnit unit,		//超时时间单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列
                              ThreadFactory threadFactory,	//线程工厂
                              RejectedExecutionHandler handler) {//拒绝策略
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

参数介绍:

corePoolSize -即使空闲时仍保留在池中的线程数,除非设置 allowCoreThreadTimeOut

maximumPoolSize - 池中允许的最大线程数

keepAliveTime - 当线程数大于内核时,这是多余的空闲线程在终止前等待新任务的最大时间。

unit - keepAliveTime参数的时间单位(多余线程的存活时间)

workQueue - 用于在执行任务之前使用的队列。 这个队列将仅保存execute方法提交的Runnable任务。

threadFactory - 执行程序创建新线程时使用的工厂,一般默认的即可

handler - 执行被阻止时使用的处理程序,因为达到线程限制和队列容量

异常

IllegalArgumentException - 如果以下某项成立

corePoolSize < 0

keepAliveTime < 0

maximumPoolSize <= 0

maximumPoolSize < corePoolSize

NullPointerException - 如果 workQueue或 threadFactory或 handler为空

手动创建线程池

4种拒绝策略

new ThreadPoolExecutor.AbortPolicy() // 队列满了还有线程进来,不处理这个线程,抛出异常

new ThreadPoolExecutor.CallerRunsPolicy() // 不处理哪里来的回哪里去

new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常!

new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会抛出异常

自定义线程池,代码:

public class Demo01 {
    public static void main(String[] args) {
        // 自定义线程池!工作 ThreadPoolExecutor
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());  //队列满了,尝试去和最早的竞争,也不会抛出异常!
        try {
            // 最大承载:Deque + max
            // 超过 RejectedExecutionException
            for (int i = 1; i <= 9; i++) {
                // 使用了线程池之后,使用线程池来创建线程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" ok");
                });
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }

    }
}

二、线程池工作原理

关于线程池的工作原理,我用下面的7幅图来展示。

1.通过execute方法提交任务时,当线程池中的线程数小于corePoolSize时,新提交的任务将通过创建一个新线程来执行,即使此时线程池中存在空闲线程。

2.通过execute方法提交任务时,当线程池中线程数量达到corePoolSize时,新提交的任务将被放入workQueue中,等待线程池中线程调度执行。

3.通过execute方法提交任务时,当workQueue已存满,且maximumPoolSize大于corePoolSize时,新提交的任务将通过创建新线程执行。

4.当线程池中的线程执行完任务空闲时,会尝试从workQueue中取头结点任务执行。

5.通过execute方法提交任务,当线程池中线程数达到maxmumPoolSize,并且workQueue也存满时,新提交的任务由RejectedExecutionHandler执行拒绝操作。

6.当线程池中线程数超过corePoolSize,并且未配置allowCoreThreadTimeOut=true,空闲时间超过keepAliveTime的线程会被销毁,保持线程池中线程数为corePoolSize。

注意:上图表达的是销毁空闲线程,保持线程数为corePoolSize,不是销毁corePoolSize中的线程。

7.当设置allowCoreThreadTimeOut=true时,任何空闲时间超过keepAliveTime的线程都会被销毁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值