线程池的工厂方法及其使用

在我之前的文章中已经讲解了线程池的构造方法以及使用,本篇文章主要讲解工作中经常用到的三种线程池的创建及使用

1、线程池状态

补充下知识点:线程池的几种状态(这点应该在上一篇文章中讲到的https://blog.csdn.net/weixin_45418455/article/details/118513730#comments_17386551)

ThreadPoolExecotor使用int的高3位来表示线程池状态,低29位表示线程数量

状态value描述
RUNNING--线程池创建出来的初始状态111能接受任务,能执行阻塞任务
SHUTDOWN--调用shutdown()方法000不接受新任务,能执行阻塞任务,会执行完现在正在执行的任务
STOP--调用shutdownNow()方法001不接受新任务,打断正在执行的任务,丢弃阻塞任务
TIDYING--中间态010任务执行完毕,活动线程也没有了
TERMINATED--终止态011线程池终结

2、工厂方法 

1.ExecutorService executorService = Executors.newFixedThreadPool(n);

//newFixedThreadPool在JDK中源码

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

结合上一篇文章的线程池核心参数,我们可以得知newFixedThreadPool线程池:

核心线程数 = 最大线程数,意味着没有空闲线程可以"救急",因此无需空闲线程的超时时间

使用的是无界的阻塞队列LinkedBlockingQueue,理论上可以放任意多的任务

此线程池适用于任务量已知,相对耗时的任务

2.ExecutorService executorService = Executors.newCachedThreadPool();

//newCachedThreadPool 在JDK中源码

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

核心线程数= 0;

最大线程数 = Integer.MAX_VALUE(2的31次方 - 1)

全部都是空闲线程,60S后未执行任务的全部回收

内部用的SynchronousQueue阻塞队列,这个队列很特殊,大家只需记住一点:队列中存在没有取走(take)的任务,下个任务就得阻塞,得等到上个任务被取走后才能入队(put)

分析下此线程池的设计:一个可根据需要创建线程的线程池,如果当前无线程可用,则创建一个新的线程并添加到池中,如果存在有使用完但是还存活的线程(未到60S)则直接复用该线程;终止并从缓存中回收那些超过60S未被使用的线程,因此,此线程池的设计不会浪费很多资源,此线程池相对灵活,适用于执行很多短期异步的任务,可提高程序性能

3.ExecutorService executorService = Executors.newSingleThreadExecutor();

//newSingleThreadExecutor 在JDK中的源码

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

核心线程数 = 1

最大线程数 = 1

没超时机制

采用LinkedBlockingQueue无界阻塞队列

看参数配置,有且只有一个线程去执行任务,任务>1是会放入无界队列排队执行,这唯一的一个线程不会被释放;好多人可能会有这样的疑问:费半天劲新建一个线程池,只有一个线程排队执行任务,这和我自己new Thread一个线程,串行执行任务有啥区别吗?区别当然是有的:如果new的线程,串行执行任务失败则会终止线程且没有任何补救措施,而线程池会新建一个线程继续执行,保障线程池的正常工作

此线程池和newFixedThreadPool(1)的区别呢?

newSingleThreadExecutor是线程个数始终为1,不可修改

newFixedThreadPool(1)初始为1,但是以后是可以修改的,对外暴露的是ThreadPoolExecutor对象,可以强转后调用setCorePoolSize()方法修改

本篇就讲到这,下一篇将总结线程池提交任务和终止任务的方法及区别

学无止境,与君共勉!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

you are so cute

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值