Java线程池 通过ThreadPoolExecutor构造器认识四种线程池

心已赠人 2022-12-14 13:45 347阅读 0赞

ThreadPoolExecutor构造器

  • int corePoolSize: 核心线程池大小
  • int maxnumPoolSize: 最大线程池大小
  • long keepAliveTime :超时时间(超时了没有人调用就会释放)

    • 特点注意: 这个超时时间控制的时非核心线程数的回收时间,核心线程永远不会被回收
  • TimeUnit unit: 超时单位
  • BlockingQueue< Runnable> workQueue: 阻塞队列(当前没有空闲线程时,任务会放入阻塞队列)
  • ThreadFactory threadFactory: 线程工厂,用来创建线程
  • RejectedExecutionHandler handler: 拒绝策略
  • 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 ||
    8. maximumPoolSize <= 0 ||
    9. maximumPoolSize < corePoolSize ||
    10. keepAliveTime < 0)
    11. throw new IllegalArgumentException();
    12. if (workQueue == null || threadFactory == null || handler == null)
    13. throw new NullPointerException();
    14. this.acc = System.getSecurityManager() == null ?
    15. null :
    16. AccessController.getContext();
    17. this.corePoolSize = corePoolSize;
    18. this.maximumPoolSize = maximumPoolSize;
    19. this.workQueue = workQueue;
    20. this.keepAliveTime = unit.toNanos(keepAliveTime);
    21. this.threadFactory = threadFactory;
    22. this.handler = handler;
    23. }

线程池类型

一般通过Executors 工具类创建线程池

SingleThreadExecutor

  • 一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,任务按照阻塞队列先进先出的顺序执行
  • 通过源码发现,SingleThreadExecutor的参数:

    • corePoolSize = 1 : 核心线程池大小为1
    • maxnumPoolSize = 1 : 最大线程池大小也为1
    • keepAliveTime = 0 : 非核心线程空闲时立刻释放(SingleThreadExecutor不会有非核心线程,因为maxnumPoolSize=corePoolSize=1,所以该参数忽略)
    • workQueue = new LinkedBlockingQueue(): 基于链表实现的阻塞队列,队列最大可容纳Integer.MAX_VALUE个任务

    public static ExecutorService newSingleThreadExecutor() {

    1. return new FinalizableDelegatedExecutorService
    2. (new ThreadPoolExecutor(1, 1,
    3. 0L, TimeUnit.MILLISECONDS,
    4. new LinkedBlockingQueue<Runnable>()));
    5. }

FixedThreadPool

  • 一个固定大小的线程池,corePoolSize=maxnumPoolSize,即核心线程数等于最大线程数
  • 如果当前运行的线程数少于corePoolSize,会立刻创建新线程执行任务,否则将任务加入到LinkedBlockingQueue中
  • 用户可以指定线程池的大小
  • 优点: 效率高,节省了创建线程的开销
  • 缺点: 不会释放工作线程,会占用一定的系统资源

    public static ExecutorService newFixedThreadPool(int nThreads) {

    1. return new ThreadPoolExecutor(nThreads, nThreads,
    2. 0L, TimeUnit.MILLISECONDS,
    3. new LinkedBlockingQueue<Runnable>());
    4. }

CachedThreadPool

  • 可缓存线程池,一个可根据需要无限(其实最大为21亿)创建新线程的线程池.
  • 如果当前没有线程可用,会创建一个新的线程来执行任务;如果还有执行完没有被销毁的线程,就会复用该线程.
  • 当有线程空闲超过一分钟后,该线程被回收释放
  • 适用场景:

    • 耗时较短的任务
    • 任务处理速度 > 任务提交速度
  • 通过源码,CachedThreadPool参数如下:

    • corePoolSize =0 :核心线程池大小为0
    • maxnumPoolSize = Integer.MAX_VALUE:线程池最大线程数为21亿
    • keepAliveTime = 60L : 非核心线程空闲存活时间为60,单位为秒(即一分钟)
    • workQueue = new SynchronousQueue(): 是一个没有数据缓冲的阻塞队列,内部没有任何存放元素的能力.每次只能put(放入)一个任务,第二次put时会被阻塞,直到take操作(取出)任务为止.同时take操作在队列为空时也处于阻塞状态

    public static ExecutorService newCachedThreadPool() {

    1. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
    2. 60L, TimeUnit.SECONDS,
    3. new SynchronousQueue<Runnable>());
    4. }

ScheduleThreadPool

  • 周期任务池(延迟任务池),主要用来在给定的延迟之后运行任务,或者定期执行任务,在功能上与Timer(定时器)类似
  • 参数定义说明:

    • corePoolSize :核心线程池大小由用户自定义
    • maxnumPoolSize = Integer.MAX_VALUE:线程池最大线程数为21亿
    • keepAliveTime =0 : 非核心空闲线程立刻回收释放
    • workQueue = new DelayedWorkQueue() :一个优先级队列,按照任务延时时间的不同进行排序,延时时间越短地就排在队列的前面,先被获取执行。

    //为了实现周期调度功能,ScheduleThreadPool的实现和前三种线程池实现不太一样
    public class ScheduledThreadPoolExecutor

    1. extends ThreadPoolExecutor
    2. implements ScheduledExecutorService {
  1. public ScheduledThreadPoolExecutor(int corePoolSize) {
  2. //调用了父类ThreadPoolExecutor的构造方法
  3. super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
  4. new DelayedWorkQueue());
  5. }
  6. }

发表评论

表情:
评论列表 (有 0 条评论,347人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java线ThreadPoolExecutor

    为什么使用线程池 如果每次使用线程都创建,每次创建和销毁的开销会很大,线程池主要用来解决线程生命周期开销问题和资源不足问题,也消除了线程创建所带来的延迟。 线