解决Java线程池任务执行完毕后线程回收问题
public static void method1() {
BlockingQueue queue = new LinkedBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS, queue);
for ( int i = 0; i < 20; i++) {
executor.execute( new Runnable() {
public void run() {
try {
System. out.println( this.hashCode()/1000);
for ( int j = 0; j < 10; j++) {
System. out.println( this.hashCode() + ":" + j);
Thread.sleep(this.hashCode()%2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System. out.println(String. format("thread %d finished", this.hashCode()));
}
});
}
}
|
debug模式下,任务执行完后,显示的效果如下:
![]() 也就是说,任务已经执行完毕了,但是线程池中的线程并没有被回收。但是我在ThreadPoolExecutor的参数里面设置了超时时间的,好像没起作用,原因如下:
工作线程回收需要满足三个条件:
1) 参数allowCoreThreadTimeOut为true 2) 该线程在keepAliveTime时间内获取不到任务,即空闲这么长时间 3) 当前线程池大小 > 核心线程池大小corePoolSize。
|
public static void method1() {
BlockingQueue queue = new LinkedBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue);
executor.allowCoreThreadTimeOut(true);
for ( int i = 0; i < 20; i++) {
executor.execute( new Runnable() {
public void run() {
try {
System. out.println( this.hashCode()/1000);
for ( int j = 0; j < 10; j++) {
System. out.println( this.hashCode() + ":" + j);
Thread. sleep(this.hashCode()%2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System. out.println(String. format("thread %d finished", this.hashCode()));
}
});
}
}
|
需要注意的是,allowCoreThreadTimeOut 的设置需要在任务执行之前,一般在new一个线程池后设置;在allowCoreThreadTimeOut设置为true时,ThreadPoolExecutor的keepAliveTime参数必须大于0。 |
public static void method1() {
BlockingQueue queue = new LinkedBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue);
for ( int i = 0; i < 20; i++) {
executor.execute( new Runnable() {
public void run() {
try {
System. out.println( this.hashCode()/1000);
for ( int j = 0; j < 10; j++) {
System. out.println( this.hashCode() + ":" + j);
Thread. sleep(this.hashCode()%2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System. out.println(String. format("thread %d finished", this.hashCode()));
}
});
}
executor.shutdown();
}
|
在任务执行完后,调用shutdown方法,将线程池中的空闲线程回收。该方法会使得keepAliveTime参数失效。 |
解决Java线程池任务执行完毕后线程回收问题的更多相关文章
- C# 多线程 线程池(ThreadPool) 2 如何控制线程池?
线程池启动了,但是没有方法去控制线程池,如果子线程出现了问题,难道线程池就死了吗? 我们可以设置线程池的线程数量,进行加入任务,线程池会自动分配并且合理的执行,但是控制不了又有啥意思呢. 线程池里线程 ...
- java并发编程(四) 线程池 & 任务执行、终止源码分析
参考文档 线程池任务执行全过程:https://blog.csdn.net/wojiaolinaaa/article/details/51345789 线程池中断:https://www.cnblog ...
- C# 本进程执行完毕后再执行下一线程
最近做了一套MES集成系统,由上料到成品使自动化运行,其中生产过程是逐步的,但是每一个动作都需要独立的线程进行数据监听,那么就需要实现线程等待. 代码: using System; using Sys ...
- 解决批处理命令执行完毕后自动关闭cmd窗口方法
问题描述: 日常开发工作中,为了节省多余操作导致浪费时间,我们经常会自己建一些批处理脚本文件(xx.bat),文件中包含我们需要执行的命令,有时候我们希望执行完毕后看一下执行的结果,但是窗口执行完毕后 ...
- 戏(细)说Executor框架线程池任务执行全过程(下)
上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现Th ...
- Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程
下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...
- 戏(细)说Executor框架线程池任务执行全过程(上)
一.前言 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不 ...
- Android AsyncTask内部线程池异步执行任务机制简要分析
如下分析针对的API 25的AsyncTask的源码: 使用AsyncTask如果是调用execute方法则是同步执行任务,想要异步执行任务可以直接调用executeOnExecutor方法,多数情况 ...
- java线程池与五种常用线程池策略使用与解析
背景:面试中会要求对5中线程池作分析.所以要熟知线程池的运行细节,如CachedThreadPool会引发oom吗? java线程池与五种常用线程池策略使用与解析 可选择的阻塞队列BlockingQu ...
随机推荐
- 题解 CF1190B 【Tokitsukaze, CSL and Stone Game】
思路: 首先题目告诉我们,一次只能删去一个石子.当然有翻译时会注意,但是看英文题时总是容易忽略.. 先排序. 然后,你会发现,有些情况是一开始就输的,具体情况如下: 有两个 两个相等非零数.(a[x] ...
- input样式去掉苹果手机的默认样式
/*<!---->去掉苹果短的样式*/ input[type="button"], input[type="submit"], input[type ...
- 容器适配器————priority_queue
#include <queue> priority_queue 容器适配器定义了一个元素有序排列的队列.默认队列头部的元素优先级最高.因为它是一个队列,所以只能访问第一个元素,这也意味着优 ...
- SQL Server 2012 sa 用户登录 18456 错误 (转)
转自:http://blog.csdn.net/waterxcfg304/article/details/40617475 最近想研究下SQL SERVER2012 Enterprise版本的数据库, ...
- VMware NAT 静态IP模式下上网
自从开始学Linux之后,对使用NAT模式上网,很是困惑.具体原理,还待求证. 使用方法(VMware): 简介: wmware在NAT使用方面很是轻松 打开本地的网络适配器. 修改虚拟网卡VMnet ...
- centos7 升级gcc9.1.0版本
centos7 环境 查缺补漏 yum install gcc gcc-c++ -y yum install bzip2 -y gcc版本下载:https://gcc.gnu.org/mirrors. ...
- 惠普DL360G6安装ESXi主机后设置多块网卡
需要先把服务器的网线连接到路由器 然后打开esxi设置网络的netwoork adapters 选中多块网卡,点确定保持 然后在到esxi客户端操作: 直接下一步 这里填上路由器分配的网段ip即可了
- React Native商城项目实战01 - 初始化设置
1.创建项目 $ react-native init BuyDemo 2.导入图片资源 安卓:把文件夹放到/android/app/src/main/res/目录下,如图: iOS: Xcode打开工 ...
- STL标准库-容器-set与map
STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_5 完成user的一对多查询操作
定义List<Account> accounts,生成getter和setter 复制AccountTest类改名UserTest类 修改测试类 还没封装所以Account的list都是n ...