V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
luxinfl
V2EX  ›  程序员

怎么写代码才能让 springboot 应用进程停止啊

  •  
  •   luxinfl · 2021-02-19 23:56:40 +08:00 · 3295 次点击
    这是一个创建于 1383 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当应用启动时,如果端口号被占用,程序会报错,但是 idea 上项目还是运行的状态。因为在端口占用前,应用起了几个线程去跑其他任务,导致应用没有正常关闭。有比较靠谱的方法可以让程序正常停止么? 有想过

    try {
        SpringApplication.run(ClcsApplication.class, args);
    }catch (Exception e){
        System.exit(0);
    }
    

    但是不建议使用。 也想过

    MyApplicationRunner implements ApplicationListener<ApplicationFailedEvent>
    

    但是需要一个个的关闭线程,而且还不一定好用。

    第 1 条附言  ·  2021-02-20 10:38:25 +08:00
    我还发现,日志里面最后两行是 shutting down ExexutorService,有个异步线程池好像也没法关掉,。
    21 条回复    2021-02-20 18:48:25 +08:00
    sutra
        1
    sutra  
       2021-02-20 00:54:01 +08:00
    你得先讓自己啟的那幾個線程終止呀。
    cslive
        2
    cslive  
       2021-02-20 08:29:11 +08:00
    windows 下打开命令窗口运行 taskkill /f /im java.exe
    yalin
        3
    yalin  
       2021-02-20 09:06:53 +08:00
    kill 进程?
    wbf1013
        4
    wbf1013  
       2021-02-20 09:10:35 +08:00 via Android
    其他线程只要是在 spring 的生命周期里就可以了,主线程挂了就全挂了
    Kinnice
        5
    Kinnice  
       2021-02-20 09:10:58 +08:00 via Android
    可以试试在最前面加个启动环境检测,检测不过就不往下走了(
    luxinfl
        6
    luxinfl  
    OP
       2021-02-20 10:21:09 +08:00
    @cslive
    @yalin 我是在想程序怎么处理,不用服务器敲命令
    luxinfl
        7
    luxinfl  
    OP
       2021-02-20 10:22:42 +08:00
    @wbf1013
    @Kinnice
    我现在把几个 kafka 的 bean 延迟启动了,但是不知道为啥,端口号被占用报错,程序还是不能正常停止。看了 dump 信息有好多线程在 waiting
    MapHacker
        8
    MapHacker  
       2021-02-20 10:33:23 +08:00
    代码里面直接 killProcess ?
    luxinfl
        9
    luxinfl  
    OP
       2021-02-20 10:37:31 +08:00
    @MapHacker 这个和直接 System.exit 一样吧,
    leeyuzhe
        10
    leeyuzhe  
       2021-02-20 10:38:28 +08:00
    打成 jar 包运行的时候会全部退出,但是在 idea 里面不会,不知道为什么
    yumenawei
        11
    yumenawei  
       2021-02-20 10:42:03 +08:00
    Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Hello world !")));
    试下这个?
    intmax2147483647
        12
    intmax2147483647  
       2021-02-20 11:33:06 +08:00
    为什么不从根本上解决问题 -> 端口冲突?
    devld
        13
    devld  
       2021-02-20 12:04:17 +08:00 via Android
    启动的几个子线程的任务中实现 DisposableBean,在回调中终止任务。
    wzcloud
        14
    wzcloud  
       2021-02-20 12:39:15 +08:00 via iPhone
    监听应用关闭事件,然后主动关闭线程;或者把那几个现场设置成守护线程?
    luxinfl
        15
    luxinfl  
    OP
       2021-02-20 16:40:51 +08:00
    @intmax2147483647 测试提出来的,没办法。而且吧端口号不能用,程序不应该退出麽。。
    luxinfl
        16
    luxinfl  
    OP
       2021-02-20 16:41:48 +08:00
    @devld 像异步线程池这个,日志就是 shutting down,这意思是不是一直在停止。。。
    luxinfl
        17
    luxinfl  
    OP
       2021-02-20 16:42:15 +08:00
    @wzcloud 怎么主动关线程,这个真不会。。。
    Kasumi20
        18
    Kasumi20  
       2021-02-20 17:00:48 +08:00
    中断其它线程,其它线程通过 Thread.sleep(0)响应中断异常
    luxinfl
        19
    luxinfl  
    OP
       2021-02-20 17:02:44 +08:00
    @Kasumi20 这不用搞个 while 循环麽?
    newmlp
        20
    newmlp  
       2021-02-20 18:18:48 +08:00
    kill -9
    devld
        21
    devld  
       2021-02-20 18:48:25 +08:00 via Android
    @luxinfl 我的理解是,线程池用 shutdownNow 停止时,会 interrupt 所有正在运行的线程。所以在任务线程中响应中断信号就可以了。
    对于被 io 阻塞的线程,interrupt 后,会抛出 InterruptedException,这时候停止任务就 ok 了;对于循环,在循环开始时,判断 Thread.isInterrupted 是否是 true,是 true 就结束循环。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1083 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:19 · PVG 03:19 · LAX 11:19 · JFK 14:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.