15线程池

本文最后更新于 2021-05-16 07:48:10

线程池

两种线程模型

  • ULT(用户线程):用户程序实现,不依赖于操作系统核心,应用提供创建,同步,调度和管理线程的函数来控制用户线程,不需要用户态,内核态的切换,速度快,内核对ULT无感知,线程阻塞则进程(包括它所有线程)阻塞
  • KLT(内核线程):系统内核管理线程,内核保存线程的状态和上下文信息,线程阻塞不会引起进程阻塞,在多处理器系统上,多线程在多处理器上运行,多线程在多处理器上并行运行。线程的创建、调度、管理由内核完成,效率比ULT忙,比进程操作快
  • JVM使用KLT线程模型

image-20201123181426745

ThreadPoolExecutor

1
2
3
4
5
6
7
8
9
10
11
12


public ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize, //最大线程数
long keepAliveTime, //非核心线程数在等在新任务多长时间后关闭
TimeUnit unit,
//阻塞队列,LinkedBlockingQueue 最大为Integer.maxSize,ArrayBlockingQueue(10)可以指定队列长度
BlockingQueue<Runnable> workQueue,
//创建线程的工厂
ThreadFactory threadFactory,
//线程池拒绝策略
RejectedExecutionHandler handler)

拒绝策略

丢弃当前线程

丢弃最老的

抛异常

当前线程执行

线程池简单结构

3c35ede5f2a76403624cc7cbb4e7154

线程池5种状态

7ae1c256983120d31d9c374a78f32cf

66d87ad5938f48a14e2a5e26a9640ca

ac8a0c38bdc9261adb0627ebc617917

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

//32-3 = 29
private static final int COUNT_BITS = Integer.SIZE - 3;

//0000 0000 0000 0000 0000 0000 0000 0001
//0001 1111 1111 1111 1111 1111 1111 1111
//2 29次方-1 容量
private static final int CAPACITY = (1 << COUNT_BITS) - 1;

//用高三位表示线程池状态
//地位表示worker数量
// runState is stored in the high-order bits
//1111 1111 1111 1111 1111 1111 1111 1111
//1110 0000 0000 0000 0000 0000 0000 0000
private static final int RUNNING = -1 << COUNT_BITS;
//0000 0000 0000 0000 0000 0000 0000 0000
private static final int SHUTDOWN = 0 << COUNT_BITS;
//0010 0000 0000 0000 0000 0000 0000 0000
private static final int STOP = 1 << COUNT_BITS;
//0100 0000 0000 0000 0000 0000 0000 0000
private static final int TIDYING = 2 << COUNT_BITS;、
//0110 0000 0000 0000 0000 0000 0000 0000
private static final int TERMINATED = 3 << COUNT_BITS;

// Packing and unpacking ctl
//获取最高三位
private static int runStateOf(int c) { return c & ~CAPACITY; }
//获取去掉高3位的数,worker数量
private static int workerCountOf(int c) { return c & CAPACITY; }
//
private static int ctlOf(int rs, int wc) { return rs | wc; }

当shutdownnow 后 队列中的 任务会执行blockingqueue的drainTo方法 移动到list,最后作为参数返回

  • 降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
  • 提高响应速度:任务到达时,无需等待线程创建即可立即执行。
  • 提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
  • 提供更多更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行。

img

①如果在线程池中的线程数量没有达到核心的线程数量,这时候就回启动一个核心线程来执行任务。

②如果线程池中的线程数量已经超过核心线程数,这时候任务就会被插入到任务队列中排队等待执行。

③由于任务队列已满,无法将任务插入到任务队列中。这个时候如果线程池中的线程数量没有达到线程池所设定的最大值,那么这时候就会立即启动一个非核心线程来执行任务。

④如果线程池中的数量达到了所规定的最大值,那么就会拒绝执行此任务,这时候就会调用RejectedExecutionHandler中的rejectedExecution方法来通知调用者。


15线程池
https://jiajun.xyz/2020/11/26/java/java基础/15线程池/
作者
Lambda
发布于
2020年11月26日
更新于
2021年5月16日
许可协议