ThreadPoolExecutor创建线程池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38069632/article/details/82560594

线程池的创建


ThreadPoolExecutor 构造器方法

public ThreadPoolExecutor(
    【必填】int corePoolSize,
    【必填】int maximumPoolSize,
    【必填】long keepAliveTime,
    【必填】TimeUnit unit,
    【必填】BlockingQueue<Runnable> workQueue,
    【可选】ThreadFactory threadFactory,
    【可选】RejectedExecutionHandler handler) {}

ThreadPoolExecutor 构造器参数

corePoolSize:线程池的基本大小

maximumPoolSize:线程池允许创建的最大线程数

keepAliveTime:线程池的工作线程空闲后,保持存活的时间

TimeUnit:线程活动保持时间的单位

workQueue:任务队列,用于保存等待执行的任务的阻塞队列

ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂统一为创建的线程设置优先级,名字,是否为守护进程等参数

RejectedExecutionHandler:饱和策略,当队列和线程池都满时,该采取什么策略处理提交的新任务

ThreadPoolExecutor 参数解析

  默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()方法,线程池才会提前创建并启动所有基本线程。

  当新任务提交时:

  若当前的 PoolSize < corePoolSize,创建新线程

  若当前的 PoolSize = corePoolSize,将任务加入工作队列等待

  若工作队列满了且 corePoolSize < maximumPoolSize,线程池会再创建新的线程执行任务。(因此若采用了无界队列,那么工作队列永远不会饱和,那么maximumPoolSize 这个参数就没什么意义了)

  若工作队列满了且 corePoolSize = maximumPoolSize,ThreadPoolExecutor根据设置的饱和策略处理提交的新任务。

AbortPolicy:默认策略,无法处理新任务时直接抛出异常
CallerRunsPolicy:只用调用者所在线程来运行任务
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
DiscardPolicy:不处理,丢弃掉

  当然,也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化存储不能处理的任务。

  阻塞队列常用种类

  ArrayBlockingQueue是一个基于数组结构的有界阻塞队列。

    public ArrayBlockingQueue(
    【必填】int capacity //队列大小
    【可选】boolean fair //是否为公平锁,默认为false
    【可选】Collection<? extends E> c //始化时加入一个集合
    ) 

  LinkedBlockingQueue是一个基于链表结构的阻塞队列,吞吐量通常要高于ArrayBlockingQueue。默认请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

    public LinkedBlockingQueue(
    【可选】int capacity //队列大小,默认为 Integer.MAX_VALUE
    【可选】Collection<? extends E> c //始化时加入一个集合
    )

  PriorityBlockingQueue是一个具有优先级的无限阻塞队列。

    public PriorityBlockingQueue(
    【必填】int initialCapacity //初始容量,默认为11,超过自动扩容
    【可选】Comparator<? super E> comparator //定义优先级比较方式
    【可选】Collection<? extends E> c //始化时加入一个集合
    ) 

  SynchronousQueue是一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于Linked-BlockingQueue。SynchronousQueue可以看成是一个传球手,负责把生产者线程处理的数据直接传递给消费者线程。队列本身并不存储任何元素,非常适合传递性场景。

    public SynchronousQueue(
    【可选】boolean fair //是否为公平锁,默认为false
    )

  DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。

    public DelayQueue(
    【可选】Collection<? extends E> c  //始化时加入一个集合
    ) 

  keepAliveTime的使用

  keepAliveTime:线程池的工作线程空闲后,保持存活的时间。所以,
如果任务很多,并且每个任务执行的时间比较短,可以调大时间,提高线程的利用率。

  时间的单位

  • TimeUnit.DAYS(天)
  • TimeUnit.HOURS(小时)
  • TimeUnit.MINUTES(分钟)
  • TimeUnit.SECONDS(秒)
  • TimeUnit.MILLISECONDS(毫秒)
  • TimeUnit.MICROSECONDS(微秒)
  • TimeUnit.NANOSECONDS(纳秒,千分之一微秒)

    参考书籍:《Java 并发编程艺术》

猜你喜欢

转载自blog.csdn.net/m0_38069632/article/details/82560594