6.执行器框架的应用ThreadPoolExecutor、Executors

执行器框架的应用

ThreadPoolExecutor

在这里插入图片描述
ThreadPoolExecutor类继承了AbstractExecutorService类,实现的ExecutorService接口,同时ExecutorService继承Executor方法

submit方法,支持Runnable、Callable参数, 返回Future对象用来处理返回结果

invokeAny和invokeAll方法,接收一个Collection集合对象,invokeAny方法表示集合中任何一个线程返回结果即返回,invokeAll方法返回所有执行结果

ThreadPoolExecutor为我们提供了4种构造函数,最多的7个参数,我们来了解这7个参数的作用
在这里插入图片描述

线程池的7个参数

在这里插入图片描述
corePoolSize:核心线程池数
maximumPoolSize:最大线程池数量

  1. 当在execute(Runnable)方法中提交新任务并且少于corePoolSize线程正在运行时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理该请求。

  2. 如果有多于corePoolSize但小于maximumPoolSize线程正在运行,则仅当队列已满时才会创建新线程。

  3. 如果队列已满,maximumPoolSize达到最大值,则执行拒绝策略

keepAliveTime 和 unit:设置非corePoolSize线程的存活时间,unit是时间单位,当线程处于空闲状态,并且超出corePoolSize的线程,将在指定时间内被回收

workQueue:工作队列,提交到线程的工作任务,workQueue的大小与线程数量有一定关系

  1. 当workQueue数量小于corePoolSize,则直接创建新线程
  2. 当workQueue数量大于corePoolSize,小于maximumPoolSize,则放到队列等待执行
  3. 当队列已满,创建新线程执行,当达到maximumPoolSize,则新任务执行拒绝策略

threadFactory:线程工厂,用于创建新线程

handler:执行拒绝策略,默认支持4种策略,也可以实现RejectedExecutionHandler自定义策略

  1. AbortPolicy:默认测策略,抛出RejectedExecutionException运行时异常;
  2. CallerRunsPolicy:使用调用者执行任务,会导致主线程堵塞,影响后续调度
  3. DiscardPolicy:直接丢弃新提交的任务;
  4. DiscardOldestPolicy:如果执行器没有关闭,队列头的任务将会被丢弃,然后执行器重新尝试执行任务(如果失败,则重复这一过程);

Executors 创建线程池

Executors 提供一系列工厂方法用于创建线程池,底层是使用ThreadPoolExecutor创建

  1. newFixedThreadPool创建固定大小的线程池
 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

可以看出corePoolSize和maximumPoolSize数量一致,即固定保存nThreads个线程,使用LinkedBlockingQueue无边界队列,需要注意内存爆满的问题

  1. newSingleThreadExecutor创建单个线程的执行器
 public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

可以看出依然使用的ThreadPoolExecutor创建线程池,但是不一样的是又包装了FinalizableDelegatedExecutorService类,那它有什么作用呢?

通过FinalizableDelegatedExecutorService包装后,它去掉了如setCorePoolSize方法,很巧妙的保证后续,不可以改变线程池的个数

这也是newFixedThreadPool(1) 和 newSingleThreadExecutor()本质的区别,newFixedThreadPool可以通过setCorePoolSize修改线程大小

  1. newCachedThreadPool带缓存线程的线程池
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

可以看出核心线程数是0,maximumPoolSize是Integer最大值,keepAliveTime是60s,也就是说60s内线程会被重用,线程数量随着任务数量不断增加,因此要注意避免执行任务时间过长的,适合执行大量的运行时间短的任务

  1. newScheduledThreadPool 周期性线程池
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
  public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

创建一个固定长度的线程池,而且以延迟或定时的方式来执行任务。
ScheduledThreadPool:核心线程池固定,大小无限的线程池。

此线程池支持定时以及周期性执行任务的需求。

线程池的状态

线程池有Runnable、Shutdown、Stop、Tidying、Terminated五种状态

Runnable
状态说明:当处于Runnable状态,线程可正常处理和添加新任务
切换说明:当线程池创建成功后,线程进入Runnable状态

Shutdown:
状态说明:当处于Shutdown状态,线程只处理队列中的任务,不接受新内容
切换说明:当调用shutdown方法后,线程池由RUNNING -> SHUTDOWN。

Stop:
状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
切换说明:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

Tidying:
状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。

切换说明:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

terminated:
状态说明:线程池彻底终止,就变成TERMINATED状态。
切换说明:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

在这里插入图片描述

本文如有任何问题,请留言指教,以免误导他人

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值