java 线程池总结

#TOC

线程池 复习(预习)

什么是线程池?

线程池是管理了一组工作线程,同时它还包括了一个用于防止等待任务队列的任务队列(阻塞队列)。

线程池体系

从左到右 → 分别表示了线程池的 接口、类继承关系

接口接口抽象类实现类
ExecutorExecutorServiceAbstractExecutorServiceThreadPoolExecutor

Executors : 类包含了建立 ThreadPool的几种静态方法,可以类比于Arrays和Collections等

Executors 类:

Executors.newSingleThread();  单个线程
Executors.newFixedThreadPool(); 固定数量线程
Executors.newCachedThreadPool(); 大小无限(取决于操作系统或者JVM的最大线程)
Executors.newScheduledThreadPool(); 大小无限(可以指定大小),支持周期性和定义的任务执行

线程池的参数

在这里插入图片描述

  1. corePoolSize : 核心线程数
  2. maximumPoolSize: 最大线程数
  3. keepAliveTime: 空闲线程最大存活时间
  4. Unit: 存活时间单位
  5. workQueue: 工作队列(阻塞队列)
  6. threadFactory:线程工程类:产生新的线程
  7. handler: 处理线程池满的处理器

workQueue的具体实现类

  1. ArrayBlockingQueue : 基于数组的FIFO队列,创建时必须制定大小
  2. LinkedBlockingQueue:基于链表的FIFO队列,可以指定大小,默认为Integer.MAX_VALUE
  3. synchronousQueue:不保存提交的任务,而是新建线程来执行新任务。只有等其他线程取走当前任务时,才能添加新任务

三种队列从上到下,吞吐量增加。

线程池执行流程

  1. 新建线程池,此时线程池内线程数量为0,(可以调用preStartThread或者preStartAllThread来提前初始化)
  2. 当有任务提交给线程池时,如果此时任务的数量小于corePoolSize,则生成一个新的线程来处理这个任务(不管此时是否有线程空闲)
  3. 当线程池中运行的线程的数量已经达到corePoolSize时,此时,缓存队列workQueue 开始发挥作用了,此时有两种情况:
    1. 当缓存队列未满:
      任务加入缓存队列
    2. 当缓存队列满:
      1. 此时当任务数量小于maximumPoolSize时,线程池会新建线程来运行当前 线程。
      2. 当任务数量已经大于maximumPoolSize时,线程池就会调用RejectExecutionHandler来处理异常。下面在介绍参数handler时会进行介绍
  4. 注意处于corePoolSizemaximumPoolSize之间的线程,会被自动释放,当线程数超过corePoolSize后,如果某个线程超过了KeepAliveTime,他就会被终止,直到线程数不大于corePoolSize,这就完成了线程数量的动态调整。

handler 4种线程池满处理机制

  1. AbortPolicy : 直接抛出异常
  2. DiscardPolicy : 丢弃当前任务
  3. DiscardOldestPolicy : 丢弃最旧的任务(队列头),并执行当前任务。
  4. CallerRunsPolicy:调用者线程执行当前任务

典型线程池结构

  1. 线程管理器 : 用于启动、停用和管理线程池
  2. 工作线程:线程池中的线程
  3. 请求接口: 创建请求对象,以供工作线程调度任务的执行
  4. 请求队列: 用于存放和提取请求
  5. 结果队列: 用于存储返回结果

线程池的5种状态

  1. Running: 能过接受新任务,对新任务做处理
  2. Shutdown: 处于shutdown状态,不接受新任务,但是可以处理已处理任务
  3. Stop: 不接受新任务,不处理已添加任务,并且中断正在进行的任务
  4. Tidying: 当所有任务已终止,线程池的状态会变成Tidying,之后会执行钩子函数terminated();
  5. Terminated: 线程池彻底结束

相关函数

  1. shutdown: 关闭线程池,不接受新任务,处理完当前已存在的任务后结束
  2. shutdownNow: 关闭线程池,不接受新任务,中断当前正在处理的任务,返回还未处理的任务

其他函数:
submit(): 有返回值,方便异常处理,可以通过Future.get抛出异常
execute(): 无返回值

参考:

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html
https://www.baeldung.com/thread-pool-java-and-guava

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值