线程池的执行流程

目录

什么是线程池

线程池的优点

线程池的执行流程 

线程池的配置参数

线程池的状态 


什么是线程池

个人理解: 线程池就是管理并维护了若干线程,并对这些线程进行分配调度以及一些别的操作,是一套具有完整执行流程的机制。

线程池内部维护了若干个线程,没有任务的时候,这些线程都处于等待空闲状态。如果有新的线程任务,就分配一个空闲线程执行。如果所有线程都处于忙碌状态,线程池会创建一个新线程进行处理或者放入队列(工作队列)中等待。

线程池的优点

  1. 线程池应用了池化的思想,主要为了减少每次获取资源的消耗,提高对资源的利用率,提供了一种限制、管理资源的策略。每个线程池还维护了一些基本统计信息,例如已完成任务的数量;
  2. 它对各个线程进行了统一管理,更加利于维护和调度;
  3. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗;
  4. 提高响应速度: 当任务到达时,可以不需要等待线程创建就能立即执行(在线程池中有空闲线程时);
  5. 提高线程的可管理性: 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,监控和调优。  

线程池的执行流程 

  1. 提交一个线程任务,线程池会分配一个空闲线程,用于执行该任务;
  2. 如果线程池中目前没有空闲线程,则线程池会判断当前"存活线程数"是否小于核心线程数corePoolSize: 
  •  如果小于核心线程数,那么会创建一个新的线程(核心线程)去处理新线程任务;
  •  如果大于核心线程数corePoolSize,线程池会检查工作队列:
  • 如果工作队列未满,则将该线程任务放入工作队列进行等待。线程池中如果出现空闲线程,则会将工作队列里的任务按照FIFO的原则取出1个并分配执行;
  • 如果工作队列已满,则判断当前线程数是否达到最大线程数maximumPoolSize:
  • 如果当前"存活线程数"没有达到最大线程数,则创建一个新线程(非核心线程)去执行新线程任务;
  • 如果当前"存活线程数"达到最大线程数maximumPoolSize,直接采用拒绝策略处理新线程任务。

总的执行流程就是: 核心线程=>工作队列=>非核心线程=>拒绝策略。

线程池的配置参数

1. corePoolSize核心线程数: 可以理解为线程池维护的最小线程数量。核心线程创建后不会被回收。大于核心线程数的线程,在空闲时间超出keepAliveTime后会被回收;

  • 在创建了线程池后,默认情况下,线程池中并没有任何线程,当调用execute()方法添加一个线程任务时,如果正在运行的线程数量小于corePoolSize,则会创建新的核心线程去执行这个任务。
  • IO密集计算:由于 I/O 设备的速度相对于 CPU来说都很慢,所以大部分情况下,I/O 操作执行的时间相对于 CPU 计算来说都非常长,这种场景我们一般都称为 I/O 密集型计算。最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]。
  • CPU密集型:CPU 密集型计算大部分场景下都是纯 CPU 计算,多线程主要目的是提升CPU利用率,最佳线程数 =“CPU 核心数 +1”。这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以临时替补,从而保证 CPU 的利用率。

2. maximumPoolSize最大线程数: 线程池允许创建的最大线程数量;(包括核心线程数)

3. keepAliveTime 非核心线程的存活时间: 当一个非核心线程的空闲时间大于keepAliveTime时,就会被回收;

  • 当线程池中的线程数大于corePoolSize时,如果一个非核心线程空闲的时间达到keepAliveTime,则会被回收,直到线程池中的线程数不超过corePoolSize。
  • 如果设置allowCoreThreadTimeOut = true,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

4. TimeUnit时间单位:参数keepAliveTime的时间单位;

5. BlockingQueue阻塞工作队列:用来存储等待执行的任务;

6. ThreadFactory线程工厂 : 用于创建线程,以及自定义线程名称,需要实现ThreadFactory接口;

7. RejectedExecutionHandler拒绝策略:当线程池线程内的线程耗尽,并且工作队列达到已满时,新提交的任务,将使用拒绝策略进行处理;

  • ThreadPoolExecutor.AbortPolicy:默认策略,丢弃任务并抛出RejectedExecutionException异常;
  • ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常;
  • ThreadPoolExecutor.DiscardOldestPolicy:丢弃工作队列中的队头任务(即最旧的任务,也就是最早进入队列的任务)后,继续将当前任务提交给线程池;
  • ThreadPoolExecutor.CallerRunsPolicy:由原调用线程处理该任务 (谁调用,谁处理);  

线程池的状态 

线程池的状态分为: RUNNING,SHUTDOWN,STOP,TIDYING,TERMINATED。

RUNNING: 运行状态,线程池一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0。该状态的线程池会接受新任务,并处理工作队列中的任务。

  • 调用线程池的shutdown()方法,可以切换到SHUTDOWN关闭状态;
  • 调用shutdownNow()方法,可以切换到STOP停止状态。

SHUTDOWN: 关闭状态,该状态的线程池不会接收新任务,但会处理工作队列中的任务;

  • 当工作队列为空时,并且线程池中执行的任务也为空时,线程池进入TIDYING状态;

STOP: 停止状态,该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;

  • 线程池中执行的任务为空,进入TIDYING状态;

TIDYING:整理状态,该状态表明所有的任务已经运行终止,记录的任务数量为0;

  • terminated()执行完毕,进入TERMINATED状态;

TERMINATED: 终止状态,该状态表示线程池彻底关闭。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值