J.Doe J.Doe - 3 months ago 18
Java Question

Run schedule in new thread

I'm querying an API to create a report and want to load that report 5 minutes later. I want to use a

ScheduledExecutorService
for that. As I don't want the Executor to block my thread, I'm creating a new thread for that, but am unsure if this is the correct way of doing this. Here's my code:

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();
}


Is there a better way to run a function 5 minutes after another? Is the way I'm doing this good? What should I change?

BTW, I'm using spring - is there something that could make that better?

Answer

ScheduledExecutorService is a good choice, but you use it incorrectly:

First of all, you don't need to create a Thread just to schedule a task from it. It adds nothing to the functionality, only wastes resources.

Second, after calling shutdown() your scheduler will no longer accept tasks, which is bad if you need to generate more than one report.

Third, since your code does nothing after the task completion, you don't need to call get() at all.

So, the only code you need is:

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

It will schedule a task and release your thread immediately. The task will be executed five minutes later in a separate thread that is managed by scheduler.

If you need some control on the scheduled tasks (check their states, cancel them etc.), you can obtain Future from schedule() and save it somewhere, but based on the code from your question, you don't need it.