ExecutorService是我们经常使用的线程池,当我们使用完线程池后,需要关闭线程池。ExecutorService的shutdown()和shutdownNow()方法都可以用来关闭线程池,那么他们有什么区别呢?

废话不多说,直接查看源码,shutdown方法:

/*** Initiates an orderly shutdown in which previously submitted* tasks are executed, but no new tasks will be accepted.* Invocation has no additional effect if already shut down.** <p>This method does not wait for previously submitted tasks to* complete execution.  Use {@link #awaitTermination awaitTermination}* to do that.** @throws SecurityException if a security manager exists and*         shutting down this ExecutorService may manipulate*         threads that the caller is not permitted to modify*         because it does not hold {@link*         java.lang.RuntimePermission}{@code ("modifyThread")},*         or the security manager's {@code checkAccess} method*         denies access.*/void shutdown();
复制代码

当我们调用shutdown()方法后,线程池会等待我们已经提交的任务执行完成。但是此时线程池不再接受新的任务,如果我们再向线程池中提交任务,将会抛RejectedExecutionException异常。如果线程池的shutdown()方法已经调用过,重复调用没有额外效应。注意,当我们调用shutdown()方法后,会立即从该方法中返回而不会阻塞等待线程池关闭再返回,如果希望阻塞等待可以调用awaitTermination()方法。

再看shutdownNow()方法:

/*** Attempts to stop all actively executing tasks, halts the* processing of waiting tasks, and returns a list of the tasks* that were awaiting execution.** <p>This method does not wait for actively executing tasks to* terminate.  Use {@link #awaitTermination awaitTermination} to* do that.** <p>There are no guarantees beyond best-effort attempts to stop* processing actively executing tasks.  For example, typical* implementations will cancel via {@link Thread#interrupt}, so any* task that fails to respond to interrupts may never terminate.** @return list of tasks that never commenced execution* @throws SecurityException if a security manager exists and*         shutting down this ExecutorService may manipulate*         threads that the caller is not permitted to modify*         because it does not hold {@link*         java.lang.RuntimePermission}{@code ("modifyThread")},*         or the security manager's {@code checkAccess} method*         denies access.*/List<Runnable> shutdownNow();
复制代码

首先shutdownNow()方法和shutdown()方法一样,当我们调用了shutdownNow()方法后,调用线程立马从该方法返回,而不会阻塞等待。这也算shutdownNow()和shutdown()方法的一个相同点。与shutdown()方法不同的是shutdownNow()方法调用后,线程池会通过调用worker线程的interrupt方法尽最大努力(best-effort)去"终止"已经运行的任务。 而对于那些在堵塞队列中等待执行的任务,线程池并不会再去执行这些任务,而是直接返回这些等待执行的任务,也就是该方法的返回值。 值得注意的是,当我们调用一个线程的interrupt()方法后(前提是caller线程有权限,否则抛异常),该线程并不一定会立马退出:

  1. 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程立即退出被阻塞状态,并抛出一个InterruptedException异常。
  2. 如果线程处于正常的工作状态,该方法只会设置线程的一个状态位为true而已,线程会继续执行不受影响。如果想停止线程运行可以在任务中检查当前线程的状态(Thread.isInterrupted())自己实现停止逻辑。

ExecutorService shutdown()和shutdownNow()方法区别相关推荐

  1. 关闭线程池 shutdown 和 shutdownNow 的区别

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://blog.csdn.net/xiewenfeng520/article/details/107013342 前 ...

  2. 正确关闭线程池:shutdown 和 shutdownNow 的区别

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/xiewenfeng520/ article/details/107013342 前言 本章分为两个议题 如何正确关闭线程池 s ...

  3. Java多线程学习九:如何正确关闭线程池?shutdown 和 shutdownNow 的区别

    如何正确关闭线程池?以及 shutdown() 与 shutdownNow() 方法的区别?首先,我们创建一个线程数固定为 10 的线程池,并且往线程池中提交 100 个任务,如代码所示. 复制代码 ...

  4. 关闭线程池 shutdown 和 shutdownNow 的区别?

    前言 本章分为两个议题 如何正确关闭线程池 shutdown 和 shutdownNow 的区别 1.线程池示例 public class ShutDownThreadPoolDemo {privat ...

  5. 关于线程池ExecutorService的shutdown()与shutdownNow()方法的区别

    2019独角兽企业重金招聘Python工程师标准>>> 问题 这两天被一个问题折腾着:一个线程池,可能会有上万个任务要执行.问题是,一旦最先运行的线程执行完,整个线程池就结束了,哪怕 ...

  6. ExecutorService对象的shutdown()和shutdownNow()的区别

    可以关闭 ExecutorService,这将导致其拒绝新任务.提供两个方法来关闭 ExecutorService.shutdown() 方法在终止前允许执行以前提交的任务,而 shutdownNow ...

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

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

  8. ThreadPoolExecutor的shutDown和shutDownNow的区别

    本篇内容转载自https://blog.csdn.net/wyc199273/article/details/65470372,自己感觉原作者代码不是很好,做了一些小修改. 先写结论: shutdow ...

  9. shutdown、shutdownNow方法的理解

    shutdown() 1.当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态.此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常. ...

最新文章

  1. 航天智慧物流创意组-技术培训二期
  2. angularJS的controller之间如何正确的通信
  3. 开启Office 2003出现要安装PRO11.MSI解决方法 (zhuan)
  4. COM编程之一 组件
  5. php调用数据库中的图片地址显示不出来,图片显示不出来,但是数据库里有显示...
  6. abb限位开关已打开drv1_广告雕刻机限位开关触发
  7. mysql可以存布尔_哪个MySQL数据类型用于存储布尔值
  8. dp打开思路4:POJ1189 UVA12511 HDU2845 HBCPC K
  9. 【电信增值业务学习笔记】3 语音类增值业务
  10. java 单文件上传_java – JIRA中的单个文件上传
  11. Redis 数据类型及应用场景
  12. java后端面试经验(自用收藏)
  13. J2EE视频实战教程网址
  14. 一个粗糙的js分页判断
  15. 【013】如何给EXCEL编写的宏设置打开密码_#VBA
  16. Directory traversal in Spring framework漏洞修复
  17. ImportError: /usr/local/lib/python3.7/dist-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: unde
  18. 详解:大数据分析的学习之路
  19. OCR识别技术 文档识别的三种形式
  20. Java并发编程总结

热门文章

  1. 组装计算机的游戏,如何组装一台游戏电脑
  2. 自动生成Android界面,面向Android的Web Service界面自动生成技术研究
  3. 计算机技术在农业上应用论文,浅谈计算机在农业中的应用论文(2)
  4. 编写运行tomcat后出现中文乱码的情况
  5. K155ID1辉光管驱动芯片功能测试
  6. 测试MindMotion 的 ISP功能 - 无法进入ISP功能
  7. 几款黄色LED的反相电流测量以及检测PCB制作要求
  8. ESP32串口转WiFi双天线ESP32-S模组
  9. 第十六届全国大学生智能车竞赛赛题规划
  10. 舵机的脉冲指令的频率对于舵机运动影响