线程池源码分析

160 阅读2分钟
  • 持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

前言

线程池的出现其实就是为了解决线程资源浪费的问题,在JAVA中创建线程是一个线程对应一个内核线程,如果常规我们使用多线程就是创建线程、执行任务、销毁线程,创建线程需要浪费资源、销毁也需要,并且在长耗时的任务上一直无创建线程也会对我们的程序造成很大的影响,于是就需要线程池来进行线程的管理跟复用。

线程池有下面几个参数:

  • 核心线程数:规定线程池的核心线程来保证处理任务的最低限度,线程池会一直保留核心线程的数量;

  • 阻塞队列:阻塞队列保证了在一定程度的任务内不会无休止的创建线程浪费资源,而是引用了队列来寄存任务;

  • 最大线程:如果超出队列的任务证明核心线程处理的时间已经赶不上任务产生的时间了,这时候就需要创建更多临时线程来处理任务降低任务量,这就是最大线程的作用;

  • 拒绝策略:如果任务数已经达到超出我们设置的最大线程数了那这部分任务我们就不再处理了,线程池已经做了三次兜底都没能扛住任务的压力,这时候就需要抛出异常来告知我们已经无法处理了。

  • 空闲时间:空闲时间是为了控制临时线程的销毁出现的,当临时线程的空闲时间超出了配置的此参数时间就会销毁

  • 时间单位:配合上面空闲时间使用的

  • 线程工厂:创建线程的工厂类

Executor

Executor是线程池相关类的顶部接口,源码非常简单,就是定义了execute方法,传参为Runnable。

image.png

Executors

Executors是线程的工厂类,我们快捷创建线程时可以使用它,但是也需要控制创建线程池的类型,它可以创建一下几种线程池,他们最终的返回都是ExecutorService

Executors.newCachedThreadPool();
Executors.newFixedThreadPool(1);
Executors.newSingleThreadExecutor();
Executors.newScheduledThreadPool(1);
Executors.newWorkStealingPool();

image.png

newFixedThreadPool

newFixedThreadPool是使用的ThreadPoolExecutor创建的线程池

image.png

newCachedThreadPool

newCachedThreadPool也是使用的ThreadPoolExecutor创建的线程池

image.png

ThreadPoolExecutor的类图

image.png

newWorkStealingPool

newFixedThreadPool是使用的ForkJoinPool创建的线程池

image.png

ForkJoinPool的类图

image.png

newSingleThreadExecutor

newFixedThreadPool是使用的FinalizableDelegatedExecutorService

image.png

FinalizableDelegatedExecutorService类图

image.png

newScheduledThreadPool

newFixedThreadPool使用的ScheduledThreadPoolExecutor,但是它继承了ThreadPoolExecutor,实际就是使用的ThreadPoolExecutor

image.png

⬇️ image.png ⬇️

image.png

ScheduledThreadPoolExecutor的类图

image.png