您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

你关闭线程池的方法安全吗?

时间:2019-11-06 11:17:35  来源:  作者:
关闭线程池我们可以选择什么都不做,JVM 关闭时自然的会清除线程池对象。当然这么做,存在很大的弊端,线程池中正在执行执行的线程以及队列中还未执行任务将会变得极不可控。所以我们需要想办法控制到这些未执行的任务以及正在执行的线程。

线程池 API 提供两个主动关闭的方

法 ThreadPoolExecutor#shutdownNow 与 ThreadPoolExecutor#shutdown,这两个方法都可以用于关闭线程池,但是具体效果却不太一样。

一、线程池的状态

在说线程池关闭方法之前,我们先了解线程池状态。

线程池状态关系图如下:

你关闭线程池的方法安全吗?

 

 

从上图我们看到线程池总共存在 5 种状态,分别为:

  • RUNNING:线程池创建之后的初始状态,这种状态下可以执行任务。
  • SHUTDOWN:该状态下线程池不再接受新任务,但是会将工作队列中的任务执行结束。
  • STOP: 该状态下线程池不再接受新任务,但是不会处理工作队列中的任务,并且将会中断线程。
  • TIDYING:该状态下所有任务都已终止,将会执行 terminated() 钩子方法。
  • TERMINATED:执行完 terminated() 钩子方法之后。

当我们执行 ThreadPoolExecutor#shutdown 方法将会使线程池状态从 RUNNING 转变为 SHUTDOWN。而调用 ThreadPoolExecutor#shutdownNow 之后线程池状态将会从 RUNNING 转变为 STOP。从上面的图上还可以看到,当线程池处于 SHUTDOWN,我们还是可以继续调用 ThreadPoolExecutor#shutdownNow 方法,将其状态转变为 STOP 。

二、ThreadPoolExecutor#shutdown

上面我们知道线程池状态,这里先说说 shutdown 方法。shutdown 方法源码比较简单,能比较直观理解其调用逻辑。

shutdown 方法源码:

你关闭线程池的方法安全吗?

 

 

shutdown 方法首先加锁,其次先检查系统安装状态。接着就会将线程池状态变为 SHUTDOWN,在这之后线程池不再接受提交的新任务。此时如果还继续往线程池提交任务,将会使用线程池拒绝策略响应,默认情况下将会使用 ThreadPoolExecutor.AbortPolicy,抛出 RejectedExecutionException 异常。

interruptIdleWorkers 方法只会中断空闲的线程,不会中断正在执行任务的的线程。空闲的线程将会阻塞在线程池的阻塞队列上。

线程池构造参数需要指定 coreSize(核心线程池数量),maximumPoolSize(最大的线程池数量),keepAliveTime(多余空闲线程等待时间),unit(时间单位),workQueue(阻塞队列)。

当调用线程池的 execute 方法,线程池工作流程如下:

  1. 如果此时线程池中线程数量小于 coreSize,将会新建线程执行提交的任务。
  2. 如果此时线程池线程数量已经大于 coreSize,将会直接把任务加入到队列中。线程将会从工作队列中获取任务执行。
  3. 如果工作队列已满,将会继续新建线程。
  4. 如果工作队列已满,且线程数等于 maximumPoolSize,此时将会使用拒绝策略拒绝任务。
  5. 超过 coreSize 数量那部分线程,如果空闲了 keepAliveTime ,线程将会终止。

工作流程图如下:

你关闭线程池的方法安全吗?

 

 

当线程池处于第二步时,线程将会使用 workQueue#take 获取队头的任务,然后完成任务。如果工作队列一直没任务,由于队列为阻塞队列,workQueue#take 将会阻塞线程。

三、ThreadPoolExecutor#shutdownNow

ThreadPoolExecutor#shutdownNow 源码如下:

你关闭线程池的方法安全吗?

 

 

shutdownNow 方法将会把线程池状态设置为 STOP,然后中断所有线程,最后取出工作队列中所有未完成的任务返回给调用者。

对比 shutdown 方法,shutdownNow 方法比较粗暴,直接中断工作线程。不过这里需要注意,中断线程并不代表线程立刻结束。这里需要线程主动配合线程中断响应。

线程中断机制: thread#interrupt 只是设置一个中断标志,不会立即中断正常的线程。如果想让中断立即生效,必须在线程 内调用 Thread.interrupted() 判断线程的中断状态。 对于阻塞的线程,调用中断时,线程将会立刻退出阻塞状态并抛出 InterruptedException 异常。所以对于阻塞线程需要正确处理 InterruptedException 异常。

 

awaitTermination

线程池 shutdown 与 shutdownNow 方法都不会主动等待执行任务的结束,如果需要等到线程池任务执行结束,需要调用 awaitTermination 主动等待任务调用结束。

调用方法如下:

你关闭线程池的方法安全吗?

 

 

如果线程池任务执行结束,awaitTermination 方法将会返回 true,否则当等待时间超过指定时间后将会返回 false。

如果需要使用这种进制,建议在上面的基础上增加一定重试次数。这个真的很重要!!!

四、优雅关闭线程池

回顾上面线程池状态关系图,我们可以知道处于 SHUTDOWN 的状态下的线程池依旧可以调用 shutdownNow。所以我们可以结合 shutdown , shutdownNow,awaitTermination ,更加优雅关闭线程池。

你关闭线程池的方法安全吗?

 



Tags:线程池   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
原文链接: https://mp.weixin.qq.com/s/MTw7z6n_wk4y4CTmGkoRoA一切要从CPU说起你可能会有疑问,讲多线程为什么要从CPU说起呢?原因很简单,在这里没有那些时髦的概念,你可以更加清...【详细内容】
2021-08-13  Tags: 线程池  点击:(97)  评论:(0)  加入收藏
多线程并发是Java语言中非常重要的一块内容,同时,也是Java基础的一个难点。说它重要是因为多线程是日常开发中频繁用到的知识,说它难是因为多线程并发涉及到的知识点非常之多,想...【详细内容】
2021-07-12  Tags: 线程池  点击:(110)  评论:(0)  加入收藏
1. Dubbo简介及线程池策略Apache Dubbo 是一款高性能、轻量级的开源 Java 服务框架。提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现...【详细内容】
2021-05-18  Tags: 线程池  点击:(202)  评论:(0)  加入收藏
在上一篇文章C++使用socket实现与微信小程序通信(下)中,小懵白就给大家简要地讲解了线程池的原理。 今天呢,小懵白就给大家继续讲解C++如何实现封装线程池类。第一步首先,我们需...【详细内容】
2021-05-14  Tags: 线程池  点击:(204)  评论:(0)  加入收藏
见字如面,我是威哥,一个从普通二本院校毕业,从未曾接触分布式、微服务、高并发到通过技术分享实现职场蜕变,成长为RocketMQ社区优秀布道师、大厂资深架构师,出版《RocketMQ技...【详细内容】
2021-03-31  Tags: 线程池  点击:(277)  评论:(0)  加入收藏
作者公众号:一角钱技术(org_yijiaoqian)前言线程池的具体实现有两种,分别是ThreadPoolExecutor 默认线程池和ScheduledThreadPoolExecutor 定时线程池,上一篇已经分析过ThreadPoo...【详细内容】
2020-12-22  Tags: 线程池  点击:(143)  评论:(0)  加入收藏
之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的...【详细内容】
2020-11-05  Tags: 线程池  点击:(91)  评论:(0)  加入收藏
前面几篇文章分析了线程的主要实现,今天来整体总结以下他们。总览图直接上总结的总览图,如下图: 如果看过前几篇文章应该基本能够看懂这张总结图,可能在单独的一篇文章里弄懂了...【详细内容】
2020-09-08  Tags: 线程池  点击:(63)  评论:(0)  加入收藏
大多数线程池实现都离不开锁的使用,如互斥量pthread_mutex*结合条件变量pthread_cond*。众所周知,锁的使用对于程序性能影响较大,虽然现有的pthread_mutex*在锁的申请与释放方...【详细内容】
2020-08-24  Tags: 线程池  点击:(87)  评论:(0)  加入收藏
作为 Java 程序员,无论是技术面试、项目研发或者是学习框架源码,不彻底掌握 Java 多线程的知识,做不到心中有数,干啥都没底气,尤其是技术深究时往往略显发憷。坐稳扶好,通过今天的...【详细内容】
2020-08-12  Tags: 线程池  点击:(48)  评论:(0)  加入收藏
▌简易百科推荐
本文分为三个等级自顶向下地分析了glibc中内存分配与回收的过程。本文不过度关注细节,因此只是分别从arena层次、bin层次、chunk层次进行图解,而不涉及有关指针的具体操作。前...【详细内容】
2021-12-28  linux技术栈    Tags:glibc   点击:(3)  评论:(0)  加入收藏
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(2)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(10)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(20)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(25)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(25)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条