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()方法。

后记

  1. 当时在网上copy了一段代码,代码里面是shutdownNow()方法,导致每次在刚执行完第一个任务时,整个线程池就结束了。因为这个原因折腾了两天,最后还是自己通过阅读JDK的代码才找到原因。

  2. 平时在用线程池的时候,直接用newFixedThreadPool、newCachedThreadPool或newSingleThreadExecutor就可以了,ThreadPoolExecutor偏底层了。

  3. 在查找问题的过程中,却搞明白了Semaphore的用法。用起来简单,用来做限流也很方便。

转载于:https://my.oschina.net/yangliu9420/blog/2988644

关于线程池ExecutorService的shutdown()与shutdownNow()方法的区别相关推荐

  1. 线程池的shutdown()与shutdownNow()方法的区别

    老习惯先上结论: shutdown只是将线程池的状态设置为SHUTWDOWN状态,正在执行的任务会继续执行下去,没有被执行的则中断. 而shutdownNow则是将线程池的状态设置为STOP,正在执行 ...

  2. ExecutorService shutdown()和shutdownNow()方法区别

    ExecutorService是我们经常使用的线程池,当我们使用完线程池后,需要关闭线程池.ExecutorService的shutdown()和shutdownNow()方法都可以用来关闭线程池,那 ...

  3. 线程池5:与停止线程池,相关的五个方法;(shutdown(),isShutdown(),isTerminated(),awaitTermination(),shutdownNow();)

    说明: (1)介绍与停止线程池相关的五个方法:shutdown(),isShutdown(),isTerminated(),awaitTermination(),shutdownNow(): 目录 一 ...

  4. 线程池shutdown和shutdownNow原理和区别

    说明:以ThreadPoolExecutor线程池为例说明整个流程(不同的线程池实现上略有差别). 一.shutdown流程 1.流程简介 修改线程池状态为SHUTDOWN 不再接收新提交的任务 中断 ...

  5. Java线程池ExecutorService中重要的方法

    ExecutorService 介绍 ExecutorService是java线程池定义的一个接口,它在java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法. Ja ...

  6. ExecutorService为创建的线程池ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE)

    ExecutorService就是要创建的线程池  JAVA中线程池用类ExecutorService代表 ,案例ExecutorService pool = Executors.newFixedTh ...

  7. Java 并发编程之线程池 ExecutorService 接口

    ExecutorService 接口继承 Executor 接口,后者只有一个executor() 方法:前者则定义了shutdown()结束线程,submit()提交任务线程,isTerminate ...

  8. java线程池需要shutdown吗_公用线程池要不要shutdown?

    最近学习了线程过后,又想学学线程池,在写测试代码的时候想到一个问题,线程太多可能会导致内存占满的问题,那线程池要不要关闭呢?怎么关闭呢? 已知关闭有两种方法,shutdown()和shutdownNo ...

  9. 线程池 ExecutorService 的使用例子

    文章目录 一.Executor 线程池的体系UML图: 二.Executor .ExecutorService .ThreadPoolExecutor 等类的说明 三.代码示例: 一.Executor ...

最新文章

  1. 某程序员吐槽:组里新来一位美女同事,男同事们冲上去大献殷勤,过几天又一哄而散!...
  2. VMware文件扩展名
  3. QML编程之旅 -- 元素布局
  4. python大神作品_掌握了这24个顶级Python库,你就是大神!
  5. 搭建mysql集群,使用Percona XtraDB Cluster搭建
  6. 多域资源整合之基础准备--DNS配置
  7. bzoj2662:[BeiJing wc2012]冻结
  8. 智慧城市排名出炉 拉动安防产业向前进
  9. 架构系列二:使用Nginx+tomcat实现集群部署
  10. CN笔记:第一章 计算机网络概述
  11. 计算机应用基础模块3实操题正确答案,国开20秋计算机应用基础作业3 模块4 PowerPoint 2010实操题答案...
  12. 发现一个特给力的编写HTML/CSS的插件——Zen Coding
  13. excel表格乱码修复_修复从数据库复制的空白Excel单元格
  14. win7注册服务器错误代码,win7系统启动不了iis服务器出现错误代码怎么解决
  15. 管家婆mysql 数据库_Java数据库小项目02--管家婆项目
  16. 教大家一个可以用迅雷全速下载百度网盘文件的方法
  17. linux 根据字母产生颜文字 figlet
  18. android新浪微博授权,新浪微博授权认证过程 - Android、iOS开发 - OSCHINA - 中文开源技术交流社区...
  19. 六轴机器人直角坐标系建立_知识篇-六轴机器人坐标
  20. [分享]错误“应用程序Xcode的这个版本不能与此版本的OS X配合使用”以及Mac源码和IOS开发资料分享

热门文章

  1. 数值选择器(NumberPicker)的功能与用法
  2. vcard java_关于vcard 文件数据格式,以备不时之需
  3. python linux系统管理与自动化运维_《Python Linux系统管理与自动化运维》赖明星著【摘要 书评 在线阅读】-苏宁易购图书...
  4. 互联网思维-产品思维(1)
  5. Appium如何获取appPackage和appActivity
  6. alert(1) to win 16
  7. c3p0 数据库连接池
  8. vc 递归删除非空文件夹
  9. h5列表页的性能优化
  10. Android--使用AIDL和远程服务实现线程通信