You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Picocli等待Javalin长运行线程,避免程序立即退出?

解决Picocli启动Javalin后程序立即退出的问题

问题场景

我想要构建一个简单的Javalin API,通过Picocli命令行参数配置HTTP端口,代码如下:

public class Main implements Runnable {

    @CommandLine.Option(names = {"-p", "--port"})
    int httpPort = 9080;

    public static void main(String... args) {
        int exitCode = new CommandLine(new Main()).execute(args);
        System.exit(exitCode);
    }

    @Override
    public void run() {
        Javalin.create()
            .get("/some/endpoint", new EndpointHandler())
            .start("0.0.0.0", httpPort);
    }
}

遇到的问题:Picocli启动Javalin线程后,程序会立即返回并退出,无法保持服务器运行。

解决方案

方案1:改用Javalin的阻塞启动方法

Javalin的start()是异步非阻塞的,启动后会直接返回,导致run()方法执行完毕,Picocli流程结束进而触发程序退出。换成startBlocking()方法即可让当前线程阻塞,直到服务器停止:

@Override
public void run() {
    Javalin.create()
        .get("/some/endpoint", new EndpointHandler())
        .startBlocking("0.0.0.0", httpPort);
}

方案2:手动阻塞主线程

如果需要保留异步启动(比如启动后要执行其他逻辑),可以在启动服务器后让线程等待服务器关闭。比如通过服务器线程的join()方法:

@Override
public void run() {
    Javalin app = Javalin.create()
        .get("/some/endpoint", new EndpointHandler())
        .start("0.0.0.0", httpPort);

    try {
        // 阻塞当前线程,直到服务器线程结束
        app.thread().join();
    } catch (InterruptedException e) {
        // 恢复中断状态
        Thread.currentThread().interrupt();
    }
}

或者用CountDownLatch监听服务器停止事件:

import java.util.concurrent.CountDownLatch;

@Override
public void run() {
    CountDownLatch shutdownLatch = new CountDownLatch(1);
    
    Javalin.create()
        .get("/some/endpoint", new EndpointHandler())
        .start("0.0.0.0", httpPort)
        .events(event -> {
            // 服务器停止时释放 latch
            event.serverStopped(shutdownLatch::countDown);
        });

    try {
        // 等待直到 latch 被释放
        shutdownLatch.await();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

核心原因

Picocli执行完run()方法后会返回并触发System.exit(exitCode),而Javalin的start()是异步启动服务器,不会阻塞当前线程,所以run()方法很快执行完毕,导致整个程序退出。使用阻塞启动方法或手动阻塞线程,就能让程序保持运行直到服务器停止。

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 19:03:35