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

Java Vertx定时任务场景下如何正确返回预期JsonObject结果

问题根因

你的代码核心问题是定时任务的执行是异步操作:调用time.schedule()后只是提交了调度任务,不会等待任务执行完成,你立刻读取ScheduledTask里的JsonObject时,run()方法还没被触发,拿到的永远是初始化的空对象。
同时你现在的写法每次接口请求都会新建一个周期性执行的Timer实例,没有销毁逻辑,会造成严重的内存泄漏。

解决方案

根据你的业务需求分两种场景调整:

场景1:仅需要单次执行业务逻辑,执行完成后返回结果

不需要自定义TimerTask,直接使用Vert.x原生的定时API即可,完全适配Vert.x的线程模型:

public void getNum(RoutingContext context){
    // 延迟0ms执行,即立即异步执行业务逻辑
    vertx.setTimer(0, timerId -> {
        JsonObject jo = new JsonObject();
        try {
            // 此处放入你原ScheduledTask中run方法的业务逻辑,获取split数组
            jo.put("file", split[0]);
            jo.put("recogTime", split[1]);
            jo.put("number", split[2]);
            log.info(jo.encodePrettily());
            // 逻辑执行完成后再返回响应
            context.response()
                    .putHeader("content-type", "application/json")
                    .setStatusCode(200)
                    .end(jo.encodePrettily());
        } catch (Exception e){
            e.printStackTrace();
            log.info("Error.Running.1stCMD");
            context.response().setStatusCode(500).end("服务执行异常");
        }
    });
}

场景2:确实需要周期性执行业务逻辑,接口返回最近一次执行的结果

不要在接口逻辑里创建定时任务,全局仅初始化一次定时任务即可:

  1. 在Verticle启动时初始化定时任务
// 作为Verticle的成员变量存储最新的执行结果
private JsonObject latestResult = new JsonObject();

@Override
public void start() throws Exception {
    // 启动周期为500ms的定时任务,全局仅启动一次
    vertx.setPeriodic(500, timerId -> {
        try {
            // 此处放入你的业务逻辑,获取split数组
            JsonObject jo = new JsonObject();
            jo.put("file", split[0]);
            jo.put("recogTime", split[1]);
            jo.put("number", split[2]);
            log.info(jo.encodePrettily());
            // 更新最新结果
            latestResult = jo;
        } catch (Exception e){
            e.printStackTrace();
            log.info("Error.Running.1stCMD");
        }
    });
    // 注册路由
    router.get("/getNum").handler(this::getNum);
}
  1. 接口直接读取最新结果返回
public void getNum(RoutingContext context){
    context.response()
            .putHeader("content-type", "application/json")
            .setStatusCode(200)
            .end(latestResult.encodePrettily());
}

注意事项
  • 如果有多个线程读写结果对象,需要加同步锁控制,避免返回半初始化的数据
  • 禁止在请求处理逻辑中重复创建周期性任务,会导致实例不断堆积最终内存溢出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:36:01