我是靠谱客的博主 懦弱荷花,最近开发中收集的这篇文章主要介绍ThreadPoolExecutor基本介绍+简单案例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 前言
    • 一、构造函数
    • 二、参数解释
    • 三、案例分析


前言

在实际开发中,线程池的创建不能使用Exectors去创建线程池,而是采用最原始的ThreadPoolExecutor来创建线程池,这样可以让编写人员更加明确线程池的运行规则,避免不必要的错误。下面我们就来看看ThreadPoolExecutor的构造参数以及它们的作用。


一、构造函数

ThreadPoolExecutor一共有四种有参构造,下面只给出参数最全的构造函数

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
                   long keepAliveTime, TimeUnit unit,
                   BlockingQueue<Runnable> workQueue,
                   ThreadFactory threadFactory, 
                   RejectedExecutionHandler handler) 

二、参数解释

  • corePoolSize:即使空闲时仍保留在池中的线程数(核心线程数)
  • maximumPoolSize:池中允许的最大线程数(核心线程数+救急线程数)
    注:救急线程是在任务数大于核心线程数时创建的线程,用于救急,用完以后过指定时间自动销毁
  • keepAliveTime:当线程数大于内核时,这是多余的空闲线程在终止前等待新任务的最大时间。
  • unit:keepAliveTime参数的时间单位
  • workQueue:用于在执行任务之前使用的队列。 这个队列将仅保存execute方法提交的Runnable任务。
  • threadFactory:执行程序创建新线程时使用的工厂
  • handler:达到线程限制和队列容量时,执行的拒绝策略

三、案例分析

  • 自定义Runnable实现类
    class MyRunnable implements Runnable {

        @Override
          public void run() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    }
  • 构造函数
     /*
        默认开启1个线程,最大可开启3个线程,
        当救急线程等待新任务超过1秒后没被使用就会销毁救急线程,
        允许2个任务进入LinkedBlockingDeque阻塞队列等待,
        用了Executors对象提供的默认线程创建工厂,
        AbortPolicy表示拒绝任务的处理程序。
         */
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                1, 3,
                1, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(2),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
  • 相关介绍:

    • LinkedBlockingDeque:是双向链表实现的双向并发阻塞队列。该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除);并且,该阻塞队列是支持线程安全。
    • AbortPolicy: 线程池的默认拒绝策略,即丢弃任务并抛出RejectedExecutionException异常。
      注:一共有4种基本的拒绝策略,这里采用默认的进行简单的案例讲解。
  • 代码1

  for (int i = 0; i <7 ; i++) {
                 Thread thread = new Thread(new MyRunnable());
                 threadPoolExecutor.execute(thread);
                 System.out.println(
                 "当前核心线程数:"+threadPoolExecutor.getCorePoolSize()
                 +" 当前池中线程数:"+threadPoolExecutor.getPoolSize()
                 +" 当前阻塞队列任务数:"+threadPoolExecutor.getQueue().size());
        }
               threadPoolExecutor.shutdown();
               /*
               执行结果:
               当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:0
               当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:1
               当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:1
               当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:2
               当前核心线程数:1 当前池中线程数:2 当前阻塞队列任务数:2
               当前核心线程数:1 当前池中线程数:3 当前阻塞队列任务数:2
               Exception in thread "main"java.util.concurrent.RejectedExecutionException
                */
  • 分析1
     第一个任务到来时,线程池为空,直接创建核心线程来处理任务
     第二个任务到来时,因为核心线程已满,则将该任务放入阻塞队列中
     第三个任务到来时,第一个任务执行完毕,取出阻塞队列中的第二个任务来执行,将第三个任务加入阻塞队列
     第四个任务到来时,因为第二个任务未执行完毕,因此加入阻塞队列中
     第五个任务到来时,因为阻塞队列已满,则创建救急线程来执行第三个任务,将第五个任务加入阻塞队列
     第六个任务到来时,因为阻塞队列已满,则创建救急线程来执行第四个任务,将第六个任务加入阻塞队列
     第七个任务到来时,因为阻塞队列已满并且最大线程数已满,则新任务无法处理,调用AbortPolicy处理,抛异常
  • 代码2
       for (int i = 0; i <6 ; i++) {
                 Thread thread = new Thread(new MyRunnable());
                 threadPoolExecutor.execute(thread);
                 System.out.println(
                 "当前核心线程数:"+threadPoolExecutor.getCorePoolSize()
                 +" 当前池中线程数:"+threadPoolExecutor.getPoolSize()
                 +" 当前阻塞队列任务数:"+threadPoolExecutor.getQueue().size());
        }

               Thread.sleep(2000);
               System.out.println(
                "当前核心线程数:"+threadPoolExecutor.getCorePoolSize()
                        +" 当前池中线程数:"+threadPoolExecutor.getPoolSize()
                        +" 当前阻塞队列任务数:"+threadPoolExecutor.getQueue().size());
               threadPoolExecutor.shutdown();
                      /*
               执行结果:
              当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:0
              当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:1
              当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:1
              当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:2
              当前核心线程数:1 当前池中线程数:2 当前阻塞队列任务数:2
              当前核心线程数:1 当前池中线程数:3 当前阻塞队列任务数:2
              当前核心线程数:1 当前池中线程数:1 当前阻塞队列任务数:0
                */
  • 分析2
前六行结果同上
第七行结果:由于此时线程任务执行完后,睡了2秒,
此时由于两个救急线程完成任务后1秒没有新任务,则救急线程销毁
线程池中只剩下核心线程

最后

以上就是懦弱荷花为你收集整理的ThreadPoolExecutor基本介绍+简单案例的全部内容,希望文章能够帮你解决ThreadPoolExecutor基本介绍+简单案例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部