今日份鸡汤:给自己时间,不要焦急;一步一步来,一日一日过。
问题:
接着上一篇的小工具,执行效率太慢了(当时也没想到会那么慢),我记得大概获取完全部数据用了40多分钟,当时忙其他事情,也就没管了,后来就想着用线程池来处理一下,然后就出现了这个问题,任务执行完,但是程序一直没有退出。
来吧,展示一下问题现象:
image.png
问题分析:
刚开始没有打印日志,以为就是数据多执行慢,后来观察输出文件的内容(上一篇的),发现数据已经都获取完了,然后就检查一下代码,确认没有哪块写错,然后就感觉隐约记得是不是要关闭线程池,这是我之前看过的内容,虽然记不清楚了,但是模糊还是有点印象的,于是就百度一下呗。果然让这个模糊的记忆一下子就清晰了:使用线程池时,在main完成之前没有调用shutdown(),使得java进程不会结束。总结来说就是:线程池默认创建的Worker线程是“非守护线程”,thread.setDaemon(false),在JDK1.5的时候,就规定了当所有非守护线程退出时,JVM才会退出,Main方法主线程和Worker线程都是非守护线程,所以不会死。
问题解决:
ExecutorService.shutdown(),就会把之前通过Executor.execute()提交的任务运行结束后关闭线程池。
这样就可以啦~
demo代码:
import java.util.concurrent.*;
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
final ExecutorService FIXED_THREAD_POOL = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new ThreadPoolExecutor.DiscardOldestPolicy());
CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
FIXED_THREAD_POOL.execute( () -> {
try {
myTest();
} catch (Exception e) {
} finally {
latch.countDown();
}
});
}
latch.await();
System.out.println("执行到这里啦。。。。。");
FIXED_THREAD_POOL.shutdown();
}
public static void myTest () {
System.out.println("this is my test !!!");
}
}
网友评论