线程池核心参数基本概念

171 阅读3分钟

1.线程池

原因: 在使用多线程的时候,如果频繁的创建销毁线程会很消耗资源,资源开销大,所以就会用到线程池。
简单描述下核心线程数,最大线程数,队列

  1. 一个任务被提交时,线程池会判断核心线程数
  2. 如果小于核心线程数,则会创建新的线程执行任务。
  3. 如果到达了核心线程数,就会放入到队列
  4. 如果队列满了就判断最大线程数
  5. 如果当前线程池的总线程数 小于 最大线程数,则创建新线程,否则执行拒绝策略。

2. ThreadPoolExecutor 参数

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

corePoolSize : 核心线程数

    线程池会维护一个核心线程数,即便是这些线程处在空闲状态也不会被销毁,除非设置了allowCoreThreadTimeOut。         
    当一个任务提交过来,线程池会检测当前线程的数量是不是小于核心线程数,
    如果小于则创建一个新的线程执行任务
    如果大于则会放到队列中
 

maximumPoolSize : 最大线程数

    当线程中队列满的时候,这时候线程会继续创建新的线程。
    但是不会一直创建新的线程,创建线程数量的多少是由maximumPoolSize 大小来定的

keepAliveTime :空闲线程存活时间

    线程池中的线程数量大于核心线程数(corePoolSize)的线程,处于空闲状态,那么会在指定的时间后销毁
    这个指定时间就是由:keepAliveTime 来指定。

unit : 单位

    keepAliveTime 计量单位。

workQueue : 工作队列

ArrayBlockingQueue

    基于数组的有界阻塞队列,按照FIFO进行排序。
    1.有界限可以防止资源被耗尽。
    2. 当线程池中的线程数达到核心线程数的时候,在有新的任务进来的时候,会放到队列的尾部,等待调用。
    3. 如果队列满了,则创建新的线程,
    4. 如果线程数达到了maximumPoolSize,则会执行拒绝策略。

LinkedBlockingQuene

基于链表的无解阻塞队列(最大:Interger.MAX(2^31-1)),按照FIFO 进行排序。
    1.当线程池的线程数达到核心线程数,该队列容量过大,所以再有新的任务进来时会存入队列,基本不会创建新的线程。

SynchronousQuene

一个不缓存的阻塞队列 
    1. 当有新任务进来时,不会缓存该任务,而是等待调度执行该任务
    2. 如果没有可用线程,则创建线程执行
    3. 如果线程数达到最大线程数,则执行拒绝策略。

PriorityBlockingQueue

    1. 具有优先级的无界阻塞对列,优先级通过参数Comparator实现。

拒绝策略:

    CallerRunsPolicy
    直接在调用者线程中执行被拒绝任务的run方法,除非线程池已经shutdown,则抛弃任务
    AbortPolicy
    直接抛弃任务,并抛出RejectedExecutionException异常。
    DiscardPolicy
    该策略下,直接丢弃任务,什么都不做。 
    DiscardOldestPolicy
    抛弃进入队列最早的那个任务,并尝试将拒绝的任务放入到队列。