美文网首页Java
Main方法里面启动一个线程池,任务执行完,为什么不会退出?

Main方法里面启动一个线程池,任务执行完,为什么不会退出?

作者: wyn_做自己 | 来源:发表于2021-11-19 14:34 被阅读0次

    今日份鸡汤:给自己时间,不要焦急;一步一步来,一日一日过。

    问题:
    接着上一篇的小工具,执行效率太慢了(当时也没想到会那么慢),我记得大概获取完全部数据用了40多分钟,当时忙其他事情,也就没管了,后来就想着用线程池来处理一下,然后就出现了这个问题,任务执行完,但是程序一直没有退出。

    来吧,展示一下问题现象:


    image.png

    问题分析:
    刚开始没有打印日志,以为就是数据多执行慢,后来观察输出文件的内容(上一篇的),发现数据已经都获取完了,然后就检查一下代码,确认没有哪块写错,然后就感觉隐约记得是不是要关闭线程池,这是我之前看过的内容,虽然记不清楚了,但是模糊还是有点印象的,于是就百度一下呗。果然让这个模糊的记忆一下子就清晰了:使用线程池时,在main完成之前没有调用shutdown(),使得java进程不会结束。总结来说就是:线程池默认创建的Worker线程是“非守护线程”,thread.setDaemon(false),在JDK1.5的时候,就规定了当所有非守护线程退出时,JVM才会退出,Main方法主线程和Worker线程都是非守护线程,所以不会死。

    问题解决:
    ExecutorService.shutdown(),就会把之前通过Executor.execute()提交的任务运行结束后关闭线程池。

    image.png

    这样就可以啦~

    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 !!!");
        }
    }
    

    相关文章

      网友评论

        本文标题:Main方法里面启动一个线程池,任务执行完,为什么不会退出?

        本文链接:https://www.haomeiwen.com/subject/yeostrtx.html