• 线程池核心类 ThreadPoolExecutor 学习


    注:ThreadPoolExecutor 核心线程池创建器,Executors中的四种预定义线程池创建方式均是基于该创建器实现

    我们以最后一个构造方法(参数最多的那个),对其参数进行解释:

    首先来看它的构造方法

     public ThreadPoolExecutor(int corePoolSize, // 1
                                  int maximumPoolSize,  // 2
                                  long keepAliveTime,  // 3
                                  TimeUnit unit,  // 4
                                  BlockingQueue<Runnable> workQueue, // 5
                                  ThreadFactory threadFactory,  // 6
                                  RejectedExecutionHandler handler ) { //7
            if (corePoolSize < 0 ||
                maximumPoolSize <= 0 ||
                maximumPoolSize < corePoolSize ||
                keepAliveTime < 0)
                throw new IllegalArgumentException();
            if (workQueue == null || threadFactory == null || handler == null)
                throw new NullPointerException();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }

    可以看到该构造方法有一下几种参数

    序号 参数名称 参数类型 参数含义
    1
    corePoolSize
    int 
    核心线程池大小
    2
    maximumPoolSize
    int 
    最大线程池大小
    3
    keepAliveTime
    long 
    线程最大空闲时间
    4
    unit
    TimeUnit 
    时间单位
    5
    workQueue
    BlockingQueue<Runnable>
    线程等待队列
    6
    threadFactory
    ThreadFactory 
    线程创建工厂
    7
    handler 
    RejectedExecutionHandler 
    拒绝策略

        

    各个参数解释

    corePoolSize

    核心线程池大小。在创建线程池之后,默认情况下线程池中并没有任何的线程,而是等待任务到来才创建线程去执行任务,当线程池中的线程数目达到 corePoolSize后,新来的任务将会被添加到线程等待队列(workQueue)中

    PS:很多人不知道这个数该填多少合适,其实也不必特别纠结,根据实际情况填写就好,实在不知道,就按照阿里工程师的写法取下列值就好了:
    int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();

    maximumPoolSize

    线程池中的最大线程数。表示线程池中最多可以创建多少个线程很多人以为它的作用是这样的:”当线程池中的任务数超过 corePoolSize 后,线程池会继续创建线程,直到线程池中的线程数小于maximumPoolSize“,其实这种理解是完全错误的。它真正的作用是:当线程池中的线程数等于 corePoolSize 并且 workQueue 已满,这时就要看当前线程数是否大于 maximumPoolSize如果小于maximumPoolSize 定义的值,则会继续创建线程去执行任务, 否则将会调用去相应的任务拒绝策略(handler)来拒绝这个任务。另外超过 corePoolSize的线程被称做"Idle Thread", 这部分线程会有一个最大空闲存活时间(keepAliveTime),如果超过这个空闲存活时间还没有任务被分配,则会将这部分线程进行回收

    keepAliveTime

    超过 corePoolSize的线程被称做"Idle Thread", 这部分线程会有一个最大空闲存活时间(keepAliveTime),如果超过这个空闲存活时间还没有任务被分配,则会将这部分线程进行回收

    unit

    keepAliveTime的时间单位

    workQueue

    阻塞队列。如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到该队列当中,注意只要超过了 corePoolSize 就会把任务添加到该缓存队列,添加可能成功也可能不成功,如果成功的话就会等待空闲线程去执行该任务,若添加失败(一般是队列已满),就会根据当前线程池的状态决定如何处理该任务(若线程数 < maximumPoolSize 则新建线程;若线程数 >= maximumPoolSize,则会根据拒绝策略做具体处理)。

    threadFactory

    线程工厂。用来为线程池创建线程,当我们不指定线程工厂时,线程池内部会调用Executors.defaultThreadFactory()创建默认的线程工厂,其后续创建的线程优先级都是Thread.NORM_PRIORITY。如果我们指定线程工厂,我们可以对产生的线程进行一定的操作。

    handler

    拒绝执行策略。当线程池的缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

    ThreadPoolExecutor.AbortPolicy:         // 丢弃任务并抛出RejectedExecutionException异常。
    ThreadPoolExecutor.DiscardPolicy:       // 也是丢弃任务,但是不抛出异常。
    ThreadPoolExecutor.DiscardOldestPolicy:    // 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy:      // 由调用线程处理该任务
  • 相关阅读:
    POJ 3356 水LCS
    POJ 2250 (LCS,经典输出LCS序列 dfs)
    POJ 1080( LCS变形)
    整数划分问题之最大乘积
    进程调度之FCFS算法(先来先运行算法)
    c模拟银行家资源分配算法
    c模拟内存分配算法(首次适应算法,最佳适应算法,最坏适应算法)
    HDU 2602 Bone Collector(经典01背包问题)
    NYOJ 44 字串和 (最大字串和 线性dp)
    匈牙利游戏(codevs 1269)
  • 原文地址:https://www.cnblogs.com/s648667069/p/12785143.html
Copyright © 2020-2023  润新知