在新线程中运行计划

时间:2016-08-24 17:50:46

标签: java multithreading scheduledexecutorservice

我查询API以创建报告,并希望在5分钟后加载该报告。我想使用ScheduledExecutorService。由于我不希望Executor阻止我的线程,我为此创建了一个新线程,但我不确定这是否是正确的方法。这是我的代码:

Thread thread = new Thread() {
        public void run() {
            log.info("Starting...");
            new RequestReport().runScheduledTask(requestId);
        }
    };
thread.start();
private void runScheduledTask(String requestId) {
    log.info("Starting five-minute countdown now...");
    ScheduledFuture<?> countdown = scheduler.schedule(() -> {
        try {
            new GetReportList().run(requestId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }, 5, TimeUnit.MINUTES);

    try {
        countdown.get();
    } catch (InterruptedException | ExecutionException e) {
        log.info("catched Exception");
        e.printStackTrace();
    }
    scheduler.shutdown();
}

有没有更好的方法在5分钟后运行一个功能?我这样做的方式好吗?我应该改变什么?

顺便说一句,我使用弹簧 - 有什么东西可以让它变得更好吗?

2 个答案:

答案 0 :(得分:4)

ScheduledExecutorService是一个不错的选择,但您使用不当:

首先,您不需要创建Thread来安排任务。它不会增加功能,只会浪费资源。

其次,在致电shutdown()之后,您的scheduler将不再接受任务,如果您需要生成多个报告,这将是不好的。

第三,由于您的代码在任务完成后没有执行任何操作,因此您根本不需要调用get()

因此,您需要的唯一代码是:

scheduler.schedule(() -> {
    try {
        new GetReportList().run(requestId);
    } catch (Exception e) {
        e.printStackTrace();
    }
}, 5, TimeUnit.MINUTES);

它将安排任务并立即释放您的线程。该任务将在五分钟后在由scheduler管理的单独线程中执行。

如果您需要对计划任务进行一些控制(检查其状态,取消它们等),您可以从Future获取schedule()并将其保存在某处,但会根据您问题中的代码,你不需要它。

答案 1 :(得分:0)

如果你想更加正确的话。关于代码,您可以将RequestReport分离到它自己的实现Runnable接口的类中,并将所述类的实例传递给Thread的构造函数