美文网首页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方法里面启动一个线程池,任务执行完,为什么不会退出?

    今日份鸡汤:给自己时间,不要焦急;一步一步来,一日一日过。 问题:接着上一篇的小工具,执行效率太慢了(当时也没想到...

  • RunLoop

    一般一个线程只能执行一个任务,执行完任务就回退出,比如c语言执行完main就退出了,而ios没有任务还是可以让程序...

  • Android线程池深入理解

    1 基本概念 线程池,就是一个线程的池子,里面有若干线程,它们的目的就是执行提交给线程池的任务,执行完一个任务后不...

  • Run Loop的理解

    RunLoop,是多线程的法宝,即一个线程一次只能执行一个任务,执行完任务后就会退出线程。主线程执行完即时任务时会...

  • Runloop【自我总结版】

    简介 起因 一般来讲,线程一次只能执行一个任务,执行完就会退出,被系统释放。所以为了实现线程执行完任务以后不退出,...

  • RunLoop学习笔记

    一般来讲,一个线程一次只能执行一个任务,执行完任务后线程就会退出。如果我们需要线程随时处理任务而不退出,通常的代码...

  • RunTime 和 RunLoop 简单总结

    RunLoop 一个线程执行一个任务,执行完成后退出。RunLoop就是执行完之后不退出,重复执行 RunLoop...

  • 最容易理解的线程池执行流程

    首先 , 当有任务时 , 看看线程池是否启动 , 启动则判断 线程数是否小于核心线程数 , 小于则执行任务 , 否...

  • 线程池——ThreadPool

    为什么要用线程池? 一个线程的执行过程可以简单概述为:创建线程——》执行任务——》销毁线程。我们只关心执行任务的环...

  • 常见异步使用方式

    1.使用thread启动一个线程执行耗时任务; 2.使用Exectors创建线程池执行多个耗时任务; 3.使用fu...

网友评论

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

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