关于线程池ExecutorService的shutdown()与shutdownNow()方法的区别
2019独角兽企业重金招聘Python工程师标准>>>
问题
这两天被一个问题折腾着:一个线程池,可能会有上万个任务要执行。问题是,一旦最先运行的线程执行完,整个线程池就结束了,哪怕队列里面还有很多任务还在等待着被执行。
有问题的代码
public static void main(String[] args){List<String> datas = new ArrayList<>();for (int i = 0; i < 15; i++){datas.add(String.valueOf(i));}BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();ExecutorService es = new ThreadPoolExecutor(2, 4,0L, TimeUnit.MILLISECONDS, queue);List<String> result = new ArrayList<>();// Semaphore lock = new Semaphore(301);for (String s : datas ) {try {// lock.acquire();es.execute(() -> {try {//执行SQL: select sleep(1) num, name from user, 让该方法的调用暂停一下TestThreadExecutor.getAll();synchronized (result){result.add(s);}} finally {//lock.release();System.out.println(">>>>>>" + s + "...queue>>>" + queue.size());}});System.out.println("----------------->" + s + "...queue>>>" + queue.size());} catch (Exception e) {e.printStackTrace();}}System.out.println("byebye~~~~~~~~~~~~~~");es.shutdownNow();try {System.out.println("wait......");es.awaitTermination(1, TimeUnit.DAYS);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("datas size>>>" + datas.size() + "###result size>>>" + result.size() + "###queue size>>>" + queue.size());}
先贴出jdk8里 shutdownNow() 与 shutdown() 方法的主要代码:
shutdownNow()
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
shutdown()
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
注意: shutdownNow()
方法的第四行drainQueue()
方法会遍历线程池的队列workQueue
,并将该队列中所有等待执行的任务全部remove掉。
drainQueue()
方法的代码:
private List<Runnable> drainQueue() {BlockingQueue<Runnable> q = workQueue;ArrayList<Runnable> taskList = new ArrayList<Runnable>();q.drainTo(taskList);if (!q.isEmpty()) {for (Runnable r : q.toArray(new Runnable[0])) {if (q.remove(r))taskList.add(r);}}return taskList;}
总结
如果队列很大,不想执行完,只想让当前正在执行中的任务执行完就立马结束,可以调用shutdownNow()
方法。如果想要队列中任务全部都执行完再结束,那么调用shutdown()
方法。
后记
当时在网上copy了一段代码,代码里面是
shutdownNow()
方法,导致每次在刚执行完第一个任务时,整个线程池就结束了。因为这个原因折腾了两天,最后还是自己通过阅读JDK的代码才找到原因。平时在用线程池的时候,直接用newFixedThreadPool、newCachedThreadPool或newSingleThreadExecutor就可以了,ThreadPoolExecutor偏底层了。
在查找问题的过程中,却搞明白了
Semaphore
的用法。用起来简单,用来做限流也很方便。
转载于:https://my.oschina.net/yangliu9420/blog/2988644
关于线程池ExecutorService的shutdown()与shutdownNow()方法的区别相关推荐
- 线程池的shutdown()与shutdownNow()方法的区别
老习惯先上结论: shutdown只是将线程池的状态设置为SHUTWDOWN状态,正在执行的任务会继续执行下去,没有被执行的则中断. 而shutdownNow则是将线程池的状态设置为STOP,正在执行 ...
- ExecutorService shutdown()和shutdownNow()方法区别
ExecutorService是我们经常使用的线程池,当我们使用完线程池后,需要关闭线程池.ExecutorService的shutdown()和shutdownNow()方法都可以用来关闭线程池,那 ...
- 线程池5:与停止线程池,相关的五个方法;(shutdown(),isShutdown(),isTerminated(),awaitTermination(),shutdownNow();)
说明: (1)介绍与停止线程池相关的五个方法:shutdown(),isShutdown(),isTerminated(),awaitTermination(),shutdownNow(): 目录 一 ...
- 线程池shutdown和shutdownNow原理和区别
说明:以ThreadPoolExecutor线程池为例说明整个流程(不同的线程池实现上略有差别). 一.shutdown流程 1.流程简介 修改线程池状态为SHUTDOWN 不再接收新提交的任务 中断 ...
- Java线程池ExecutorService中重要的方法
ExecutorService 介绍 ExecutorService是java线程池定义的一个接口,它在java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法. Ja ...
- ExecutorService为创建的线程池ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE)
ExecutorService就是要创建的线程池 JAVA中线程池用类ExecutorService代表 ,案例ExecutorService pool = Executors.newFixedTh ...
- Java 并发编程之线程池 ExecutorService 接口
ExecutorService 接口继承 Executor 接口,后者只有一个executor() 方法:前者则定义了shutdown()结束线程,submit()提交任务线程,isTerminate ...
- java线程池需要shutdown吗_公用线程池要不要shutdown?
最近学习了线程过后,又想学学线程池,在写测试代码的时候想到一个问题,线程太多可能会导致内存占满的问题,那线程池要不要关闭呢?怎么关闭呢? 已知关闭有两种方法,shutdown()和shutdownNo ...
- 线程池 ExecutorService 的使用例子
文章目录 一.Executor 线程池的体系UML图: 二.Executor .ExecutorService .ThreadPoolExecutor 等类的说明 三.代码示例: 一.Executor ...
最新文章
- 某程序员吐槽:组里新来一位美女同事,男同事们冲上去大献殷勤,过几天又一哄而散!...
- VMware文件扩展名
- QML编程之旅 -- 元素布局
- python大神作品_掌握了这24个顶级Python库,你就是大神!
- 搭建mysql集群,使用Percona XtraDB Cluster搭建
- 多域资源整合之基础准备--DNS配置
- bzoj2662:[BeiJing wc2012]冻结
- 智慧城市排名出炉 拉动安防产业向前进
- 架构系列二:使用Nginx+tomcat实现集群部署
- CN笔记:第一章 计算机网络概述
- 计算机应用基础模块3实操题正确答案,国开20秋计算机应用基础作业3 模块4 PowerPoint 2010实操题答案...
- 发现一个特给力的编写HTML/CSS的插件——Zen Coding
- excel表格乱码修复_修复从数据库复制的空白Excel单元格
- win7注册服务器错误代码,win7系统启动不了iis服务器出现错误代码怎么解决
- 管家婆mysql 数据库_Java数据库小项目02--管家婆项目
- 教大家一个可以用迅雷全速下载百度网盘文件的方法
- linux 根据字母产生颜文字 figlet
- android新浪微博授权,新浪微博授权认证过程 - Android、iOS开发 - OSCHINA - 中文开源技术交流社区...
- 六轴机器人直角坐标系建立_知识篇-六轴机器人坐标
- [分享]错误“应用程序Xcode的这个版本不能与此版本的OS X配合使用”以及Mac源码和IOS开发资料分享
热门文章
- 数值选择器(NumberPicker)的功能与用法
- vcard java_关于vcard 文件数据格式,以备不时之需
- python linux系统管理与自动化运维_《Python Linux系统管理与自动化运维》赖明星著【摘要 书评 在线阅读】-苏宁易购图书...
- 互联网思维-产品思维(1)
- Appium如何获取appPackage和appActivity
- alert(1) to win 16
- c3p0 数据库连接池
- vc 递归删除非空文件夹
- h5列表页的性能优化
- Android--使用AIDL和远程服务实现线程通信