首页新闻博问专区闪存班级 我的博客我的园子账号设置退出登录注册登录AnonyStar博客园 首页 新随笔 联系订阅 管理 随笔 - 22 文章 - 0 评论 - 10 优雅关闭线程池的方案 我们经常在项目中使用的线程池,但是是否关心过线程池的关闭呢,可能很多时候直接再项目中直接创建线程池让它一直运行当任务执行结束不在需要了也不去关闭,这其实是存在非常大的风险的,大量的线程常驻在后台对系统资源的占用是巨大的 ,甚至引发异常。所以在我们平时使用线程池时需要注意优雅的关闭,这样可以保证资源的管控。在 Java 中和关闭线程池相关的方法主要有如下: void shutdown()List shutDownNowboolean awaitTerminationboolean isShutDownboolean isTerminated对于这些方法有着不同的使用和作用,下面我们真的会这些不同的方法做详细的介绍。ShutDownshutDown 方法从字面意思我们可以看到是停止关闭的意思,我们先来看下面的一段代码,首先我们通过 ThreadPoolExecutor 来创建一个容量是10的无界线程池,与 FixedThreadPool 类似的,这里手动创建可以更好地理解线程池的创建。在后我们提交一千个任务执行,再执行 shutdown 方法进行暂停。 public static void main(String[] args) throws InterruptedException {
ExecutorService service = new ThreadPoolExecutor(
10,
10,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>());
for (int i = 0; i < 1000; i++) {
service.submit(() ->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("接受中断,不处理~~");
}
System.out.println("args = " + Arrays.deepToString(args)+ Thread.currentThread().getName());
});
}
service.shutdown();
}
我们可以看到结果所以线程会正常执行结束后再关闭线程池,对于 ShutDown 而言它可以安全的停止一个线程池,它有几个关键点ShutDown 会首先将线程设置成 SHUTDOWN 状态,然后中断所有没有正在运行的线程正在执行的线程和已经在队列中的线程并不会被中断,说白了就是使用shutDown 方法其实就是要等待所有任务正常全部结束以后才会关闭线程池调用 shutdown() 方法后如果还有新的任务被提交,线程池则会根据拒绝策略直接拒绝后续新提交的任务。ShutDownNow这个方法与上面方法相比较,直观就是 now ,即立即停止任务,同样是上述案列,略作修改如下,public static void main(String[] args) throws InterruptedException {
ExecutorService service = new ThreadPoolExecutor(
10,
10,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1000));
for (int i = 0; i < 1000; i++) {
service.submit(() ->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("接受中断,结束线程~~");
//这里响应中断
return;
}
System.out.println("args = " + Arrays.deepToString(args)+ Thread.currentThread().getName());
});
}
final List<Runnable> runnables = service.shutdownNow();
System.out.println(runnables);
}
执行上述代码我们发现,当执行shutDownNow 方法后,会像全部正在运行的队列通知中断,正在运行的线程接收到中断信号后选择处理,而在队列中的全部取消执行转移到一个list队列中返回,如上述 List runnables ,这里记录了所有终止的线程awaitTermination这个方法并不是用来关闭线程池的,首先我们看一下这个方法的定义:boolean awaitTermination_(long timeout, TimeUnit unit)_可以看到这个方法有两个参数,timeout 表示等待的时间,unit 时间单位这个方法的作用是,调用后等待timeout时间后,反馈线程池的状态,等待期间(包括进入等待状态之前)线程池已关闭并且所有已提交的任务(包括正在执行的和队列中等待的)都执行完毕,相当于线程池已经“终结”了,方法便会返回 true;等待超时时间到后,第一种线程池“终结”的情况始终未发生,方法返回 false;等待期间线程被中断,方法会抛出 InterruptedException 异常。上面代码可以修改来测试,这里不再粘贴代码isShutDownisShutDown 方法正如名字,判断线程池是否停止,返回的是 Boolean 类型,如果已经开始停止线程池则返回 true 否则放回false当调用了shutDown 或shutDownNow 时之后,会返回 true 不过需要注意,这时候只是代表线程池关闭流程的开始,并不是说线程池已经停止了isTerminated这个方法与上面的方法的区别就是这是正真检测线程池是否真的终结了这不仅代表线程池已关闭,同时代表线程池中的所有任务都已经都执行完毕了,因为在调用 shutdown 方法之后,线程池会继续执行里面未完成的任务,包括正在执行的任务和在任务队列中等待的任务。如果调用了 shutdown 方法,但是有一个线程依然在执行任务,那么此时调用 isShutdown 方法返回的是 true,而调用 isTerminated方法返回的便是 false,因为线程池中还有任务正在在被执行,线程池并没有真正“终结”。直到所有任务都执行完毕了,调用 isTerminated() 方法才会返回 true,这表示线程池已关闭并且线程池内部是空的,所有剩余的任务都执行完毕了。本文由AnonyStar 发布,可转载但需声明原文出处。
欢迎关注微信公账号 :云栖简码 获取更多优质文章
更多文章关注笔者博客 :云栖简码 i-code.online好文要顶 关注我 收藏该文 AnonyStar
关注 - 1
粉丝 - 5 +加关注 0 0
« 上一篇: JAVA中常见的阻塞队列详解 posted @ 2020-11-23 15:43 AnonyStar 阅读(265) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
发表评论 【福利】注册AWS账号,立享12个月免费套餐 编辑预览 7693b08a-a8f6-49f3-f45a-08d88556cc23 Markdown 帮助自动补全 不改了退出 订阅评论 [Ctrl+Enter快捷键提交]
首页 新闻 博问 专区 闪存 班级 【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】从零开始的RPG游戏制作教程,来《魔兽争霸III》共同成长
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动
【福利】AWS携手博客园为开发者送免费套餐与抵扣券
【推荐】 阿里云折扣价格返场,错过再等一年
相关博文:
· 线程池
· 线程池
· 线程池
· 并发编程----GIL,进程池/线程池
· 连接池
» 更多推荐…最新 IT 新闻:
· 整整10年了!这就是微信的第一段代码
· Google Assistant现在可以用来控制智能灯具
· 微软投资2700万欧元在爱尔兰开设工程中心 设立200个新岗位
· 开发人员已进行175小时《赛博朋克2077》 仍未打完
· 谷歌Stadia云游戏即将在iPhone上推出公测版本
» 更多新闻…
公告 昵称: AnonyStar
园龄: 6个月
粉丝: 5
关注: 1 +加关注
< 2020年11月> 日一二三四五六 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 1 2 3 4 5 6 7 8 9 10 11 12
搜索 常用链接 我的随笔我的评论我的参与最新评论我的标签我的标签java(14) spring(5) ioc(2) spring data(1) 跨域(1) 源码(1) java,web(1) jpa(1) github actions(1) githubpage(1) 更多 随笔档案 2020年11月(4) 2020年10月(5) 2020年9月(3) 2020年8月(1) 2020年6月(2) 2020年5月(7) 最新评论1. Re:[高频面试]解释线程池的各个参数含义早哈–fen儿2. Re:总算把线程六种状态的转换说清楚了!很细节 很棒–winds_随风3. Re:Java并发编程-线程基础博主你这文章写不错啊,你这文章正好帮助我学习这块,可以的。我也是专注于Java架构技术的程序员,欢迎关注 : Java架构技术方案…–jack_wang_king4. Re:Java操作Elasticsearch 之 [Java High Level REST Clientedit]很赞。我也写了一个系列 Elasticsearch For .Net项目实战
是ES LowLevelClient的–戎"码"一生5. Re:Hexo+GitHub Actions 完美打造个人博客@luquanren 这里需要缺分一下,我们如果用的是GitHubPage ,那么也是已经生成静态资源的这个仓库暴露出去,而不需要把源码仓库暴露出去,像我们的博客都是md格式的,放在源码库中,通过编译…–AnonyStar阅读排行榜 1. Hexo+GitHub Actions 完美打造个人博客(903) 2. Web 跨域请求问题的解决方案- CORS 方案(652) 3. Java操作Elasticsearch 之 Java High Level REST Clientedit 4. 如何优雅的停止一个线程?(360) 5. 重新认识 Spring IOC(335) 评论排行榜 1. Hexo+GitHub Actions 完美打造个人博客(5) 2. [高频面试]解释线程池的各个参数含义(1) 3. 总算把线程六种状态的转换说清楚了!(1) 4. Java并发编程-线程基础(1) 5. Java操作Elasticsearch 之 Java High Level REST Clientedit 推荐排行榜 1. 总算把线程六种状态的转换说清楚了!(2) 2. Hexo+GitHub Actions 完美打造个人博客(2) 3. 重新认识 Spring IOC(2) 4. 基于synchronized锁的深度解析(1) 5. 知道线程池的四种拒绝策略吗?(1)
Copyright © 2020 AnonyStar
Powered by .NET 5.0.0 on Kubernetes