背景

来来,先看一段代码,这段代码会发生什么?当然这段代码是有问题的。

public static void main(String[] args) {for(int i = 0; i < 100; i++) {test(i);}try {Thread.currentThread().join();} catch(InterruptedException e) {e.printStackTrace();}}private static void test(int i) {final ExecutorService executorService = Executors.newFixedThreadPool(50);executorService.submit(new Runnable() {@Overridepublic void run() {}},"thread"+i);}
复制代码

分析

结果

会有100个线程池,有5000个线程,可能有人会问为什么?难道线程池的不会根据test方法执行完直接退出吗?

我们看下运行的结果

吃惊吧!

赶紧去看了ThreadPoolExecutor的源码,找到这么一段话

A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed even if users forget to call shutdown, then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or setting allowCoreThreadTimeOut(boolean)

大概的意思: 在线程池中很长时间不再引用且没有剩余线程,线程池将自动关闭。如果您希望确保未引用的池被回收,即使用户忘记调用shutdown,那么必须安排未使用的线程最终死亡,通过设置适当的保持生存时间,使用一个零核心线程或allowCoreThreadTimeOut(boolean)。

总结下: 线程池里面没有核心线程了,线程池会退出,其实这里可以使用Executors.CachedThreadPool 他的核心线程池就是0.当然他会有一个等待时间60L,来标记核心线程池的存活时间

public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}
复制代码

我们看下allowCoreThreadTimeOut的方法

allowCoreThreadTimeOut的注释 Sets the policy governing whether core threads may time out and terminate if no tasks arrive within the keep-alive time, being replaced if needed when new tasks arrive. When false, core threads are never terminated due to lack of incoming tasks. When true, the same keep-alive policy applying to non-core threads applies also to core threads. To avoid continual thread replacement, the keep-alive time must be greater than zero when setting true. This method should in general be called before the pool is actively used.

设置控制核心线程是否可以超时和终止的策略, 如果没有任务在保持生存时间内到达, 则在新任务到达时需要替换。 当错误时, 由于缺少传入任务, 核心线程永远不会被终止。 如果为 true, 则适用于非核心线程的相同的保持生存策略也适用于核心线程。为避免连续线程替换, 设置 true 时, 保持生存时间必须大于零。此方法通常应在池被积极使用之前调用。

 public void allowCoreThreadTimeOut(boolean value) {if (value && keepAliveTime <= 0)throw new IllegalArgumentException("Core threads must have nonzero keep alive times");if (value != allowCoreThreadTimeOut) {allowCoreThreadTimeOut = value;if (value)// 关键这里,将线程的worker都中断interruptIdleWorkers();}}
复制代码

总结

使用完线程需要调用shutdown 或者shutdownNow 线程池要创建为全局变量

转载于:https://juejin.im/post/5b99f13ee51d450e8a65e0b1

[并发]线程池关闭的问题相关推荐

  1. Java并发—线程池ThreadPoolExecutor基本总结

    原文作者:Matrix海子 原文地址:Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线 ...

  2. Executors线程池关闭时间计算

    Executors线程池关闭时间计算 学习了:http://blog.csdn.net/wo541075754/article/details/51564359 https://www.cnblogs ...

  3. java 并发线程池的理解和使用

    一.为什么要用线程池 合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要的等到线程创建就能立 ...

  4. ThreadPoolExecutor(五)——线程池关闭相关操作

    补充了和Thread的interrupt操作相关的知识,回头再来看ThreadPoolExecutor中interrupt,关闭线程池等相关操作. 1.shutdown /*** Initiates ...

  5. ThreadPoolExecutor(六)——线程池关闭之后

    上一篇主要从代码角度介绍了线程池关闭相关的方法,包括各个方法之间的逻辑关系,调用关系和产生的效果. 这一篇更多从逻辑角度上来说一下线程池在shutdown之后,原来正常的处理流程有哪些变化,既是总结也 ...

  6. 并发编程五:java并发线程池底层原理详解和源码分析

    文章目录 java并发线程池底层原理详解和源码分析 线程和线程池性能对比 Executors创建的三种线程池分析 自定义线程池分析 线程池源码分析 继承关系 ThreadPoolExecutor源码分 ...

  7. 探索JAVA并发 - 线程池详解

    作者:acupt,80后资深Java工程师一枚!架构师社区合伙人! 线程池是并发编程中必不可少的一种工具,也是面试高频话题. 线程池,即管理着若干线程的资源池(字面意思).相比于为每个任务分配一个线程 ...

  8. java线程池拒绝策略_Java核心知识 多线程并发 线程池原理(二十三)

    线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后 启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕, 再从队列中取出任务来执行.他 ...

  9. Java 编程问题:十、并发-线程池、可调用对象和同步器

    原文:Java Coding Problems 协议:CC BY-NC-SA 4.0 贡献者:飞龙 本文来自[ApacheCN Java 译文集],自豪地采用谷歌翻译. 本章包括涉及 Java 并发的 ...

  10. 27.Linux网络编程socket变成 tcp 高并发 线程池 udp

    好,咱们开始上课了,从今天开始咱们连续讲 8 天的,网络编程这个还是在linux环境下去讲,咱们先看一下咱们这 8 天都讲什么东西,跟大家一块来梳理一下,你先有个大概的印象,这些你也不要记,那么网络编 ...

最新文章

  1. Unicode编码Linux下的转换
  2. 最优化问题的求解分类
  3. 利用VC++实现局域网实时传输
  4. jxl导入/导出excel(网上的案例)
  5. Educational Codeforces Round 58
  6. 中国企业人工智能应用之道——从“浅尝试”到“规模化”.pdf(附下载链接)...
  7. 感觉小轿车要比SUV舒服,为什么很多人还是选择了SUV?
  8. Windows7 64位下SDK Manager.exe无法运行问题解决方法
  9. 关于WPF的MVVM模式的吐槽
  10. OBS Studio录屏软件安装和使用教程
  11. 线性四叉树的实现C++
  12. CrossApp推出移动应用开发神器 CrossApp Style
  13. 效果图软件选择手册 | Lumion、VRay、Conora、Enscape...你适合用什么软件做效果图?
  14. 【实用性程序】弧微分计算圆周长
  15. 【渝粤题库】陕西师范大学200391 初等几何研究 作业(专升本)
  16. 计算机学院静态网页毕业论文,静态网页毕业论文静态网页毕业论文.doc
  17. ffmpeg视频裁剪
  18. Google版 “AirDrop” 姗姗来迟,万能联播缘何超越Nearby Sharing?
  19. 【Leetcode】1925. Count Square Sum Triples
  20. 旁路电容和去耦电容基础知识

热门文章

  1. Atitit 语义网的实现技术 目录 1. 语义网概念及技术综述 1 2. 图2-1 语义网的体系结构 2 2.1. 第1层:基础层,主要包含Unicode和URI(Uniform resource
  2. atitit.RESTful服务的概览and框架选型
  3. paip.设置鼠标灵敏度API
  4. 搞明白“清算-结算”的二级制
  5. Julia : REPL中的一些快捷键
  6. 摆动定价机制连载系列之推出背景及工作原理介绍
  7. (转)以太坊的 Merkle 树
  8. Rust : range,[],vec,array中元素的类别
  9. 2020传道(原中国开源圈)开源寄语
  10. 【图像压缩】基本matlab DCT+量化+huffman JPEG图像压缩【含Matlab源码 1217期】