本篇原创发布于: java 线程池使用后到底要不要关闭
直接上实验代码
public static void main(String[] args) throws Exception {
//用于获取到本
java进程,进而获取总线程数
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
String jvmName = runtimeBean.getName();
System.out.println("JVM Name = " + jvmName);
long pid = Long.valueOf(jvmName.split("@")[0]);
System.out.println("JVM PID = " + pid);
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
int n = 30000;
for (int i = 0; i < n; i++) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10,20,1000,TimeUnit.SECONDS,new LinkedBlockingDeque<>());
for(int j=0;j<10;j++){
executor.execute(()->{
System.out.println("当前线程总数为:"+bean.getThreadCount());
});
}
}
Thread.sleep(10000);
System.out.println("线程总数为 = " + bean.getThreadCount());
}
简单来说就是在一个 for 循环中创建线程池,然后执行一个打印任务(不执行任务线程不会真正创建),打印出当前 java 进程的总线程数,下面是打印部分结果:
可以看到在创建到 15 万个线程是爆内存,内存占用百分百后 java 应用崩溃。说明线程未被回收。
PS:内存占用百分百后,部分应用开始出现异常,界面花屏,闪屏,不能正常绘制gui,不知道为啥,即使后面内存占用降下来也一样,只能重启应用。
结论
使用完线程池一定记得回收,否则跑着跑着就内存爆炸崩溃。回收函数如下:
//执行此函数后线程池不再接收新任务,并等待所有任务执行完毕后销毁线程。此函数不会等待销毁完毕
executor.shutdown();
//立即结束所有线程,不管是否正在运行,返回未执行完毕的任务列表
executor.shutdownNow();
本篇原创发布于: java 线程池使用后到底要不要关闭