terminated 线程_项目中的线程池你理解多少

线程是稀缺资源,他的创建与销毁是比较重且消耗资源的操作,而java线程依赖于内核线程,创建线程需要进行系统状态切换,为避免资源过度消耗需要设法重用线程执行多个任务,线程池就是一个线程的缓存,负责对线程进行统一分配、调优与监控。

首先我们为什么要使用线程池?

1.降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

2.提高响应速度:当任务到达时,可以不需要等待线程创建就能立即执行。

3.提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,监控和调优。

线程池的创建以及参数的设置

96b87a0be636783956e6131f0147e7a6.png

从图中我们可以了解到Executor是一个父类,我们项目中创建线程池最常用的方式就是使用他的子类TreadPoolExecutor类,那么我们就看下这里面需要设置的参数 代码 如下 :

5c4dee11fa834f71b5081b3bff754af3.png

CORE_POOL_SIZE:核心线程数定义了最小可以同时运行的线程数量。

MAXMUM_POOL_SIZE:当队列中存放的任务到达队列容量的时候,当前可以同时运行的线程数量变为最大线程数。

QUEUE_CAPACITY:当新任务加入会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,任务就会被存放到队列中。

KEEP_ALIVE_TIME:当线程池中的线程数量大于核心线程数时,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过KEEP_ALIVE_TIME才会被回收销毁。

ThreadPoolExecutor.CallerRunsPolicy():调用执行自己的线程运行任务,也就是直接在调用execute方法的线程运行(run)被拒绝的任务,如果执行程序已关闭,则会丢弃任务。因此这种策略会降低新任务的提交速度,影响程序的整体性能。另外,这个策略喜欢增加队列容量。如果应用程序可以承受此延迟并且不能任务丢弃一个任务请求的话,可以选择这个策略。

线程池的运行原理

5f5fa16a13fd4301cba85369270b8cb3.png

  1. 首先当所有任务请求过来后,会分发给Excecute然后Excecute会调用线程池的核心线程去处理任务,如果这个时候又有请求过来Excecute会把请求的任务放在队列里面,比如最大队列存储数量为5,当请求的任务队列里面放满的时候Excecute会调用临时线程去处理任务。

  2. 如果此时还有大量的任务请求过来,这个时候线程池会执行拒绝策略,不在接受新的任务,并抛出异常

  3. 如果线程在运行的过程中发生异常,此时该线程会停止工作,线程池会重新创建一个新的线程去执行任务。

线程池的五种状态

5a85d2d1688b1dc59215e35e9ebe2168.png

1、RUNNING

(1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。
(2) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

2、 SHUTDOWN

(1) 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。
(2) 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。

3、STOP

(1) 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
(2) 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

4、TIDYING

(1) 状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。
(2) 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

5、 TERMINATED

(1) 状态说明:线程池彻底终止,就变成TERMINATED状态。
(2) 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

我们看一下源码

828f01703f315f28e424b8d1e9c1c4eb.png

f891bfffb1ad9be491e1dee7e1705e3d.png

e544bfd7d73949e01fcbc2c17ee23604.png

通过源码的解析我们可以对线程池的应用会更加的了解,谢谢大姐关注以后会有更多干货和大家分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值