当前位置:   article > 正文

「超详细」Java线程池源码解析

java线程池源码

绕不开的线程池

只看ThreadPoolExecutor的英文语义就能知道这是一个与线程池有关的类。

关于线程池,搞过开发的肯定都知道,也都能或多或少讲出相关知识;尽管如此,作者在还是想要不厌其烦的给大家加深加深记忆

线程池是一种池化技术,Java中类似的池化技术有很多,
常见的有:

  • 数据库连接池
  • redis连接池
  • http连接池
  • 内存池
  • 线程池

池化技术的作用:把一些能够复用的东西(比如说连接、线程)放到初始化好的池中,便于资源统一管理。
这样做的好处:

避免重复创建、销毁、调度的开销,提高性能 保证内核的充分利用,防止过分调度 自定义参数配置达到最佳的使用效果

ThreadPoolExecutor 知识点

Java中创建线程池的方法

不推荐

通过Executors类的静态方法创建如下线程池

  • FixedThreadPool (固定个数)
  • ScheduledThreadPool (执行周期性任务)
  • WorkStealingPool (根据当前电脑CPU处理器数量生成相应线程数)
  • CachedThreadPool (带缓存功能)
  • SingleThreadPool (单个线程)

 

推荐

通过ThreadPoolExecutor创建线程池

  1. // 给线程定义有业务含义的名称
  2. ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-pool-%s").build();
  3. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
  4. 5, // 线程池核心线程数
  5. 10, // 线程池最大线程数,达到最大值后线程池不会再增加线程
  6. 1000, // 线程池中超过corePoolSize数目的空闲线程最大存活时间
  7. TimeUnit.MILLISECONDS, // 时间单位,毫秒
  8. new LinkedBlockingQueue<>(50), // 工作线程等待队列
  9. threadFactory, // 自定义线程工厂
  10. new ThreadPoolExecutor.AbortPolicy()); // 线程池满时的拒绝策略
  11. 复制代码

为什么

先来看看阿里巴巴出品的《Java开发手册》中怎么说?

 

再来看看源码怎么写? 

以SingleThreadPool为例,其实现也是通过ThreadPoolExecutor的构造方法创建的线程池, 之所以不推荐的原因是其使用了LinkedBlockingQueue作为工作线程的等待队列,其是一种无界缓冲等待队列,该队列的默认构造器定义的长度为Integer.MAX_VALUE 

FixedThreadPool同理 

CachedThreadPool采用了SynchronousQueue队列,也是一种无界无缓冲等待队列,而且其最大线程数是Integer.MAX_VALUE 

ScheduledThreadPool采用了DelayedWorkQueue队列,是一种无界阻塞队列,其最大线程数是Integer.MAX_VALUE 

以上四种线程池都有OOM的风险
相反,在使用ThreadPoolExecutor时,我们可以指定有界/无界阻塞队列,并指定初始长度。

ThreadPoolExecutor源码分析

线程池生命周期

 

Tips:千万不要把线程池的状态和线程的状态弄混了。补一张网上的线程状态图 

Tips:当线程调用start(),线程在JVM中不一定立即执行,有可能要等待操作系统分配资源,此时为READY状态,当线程获得资源时进入RUNNING状态,才会真正开始执行。

拒绝策略

  • CallerRunsPolicy(在当前线程中执行)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/944582
推荐阅读
相关标签
  

闽ICP备14008679号