Why does Java's scheduleWithFixedDelay work with a Runnable but not a FutureTask wrapping a runnable?
This can be shown pretty easily with two different code samples:
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("beep");
return 1;
}
}), 1, 5, TimeUnit.SECONDS);
produces:
beep
But the application does not exit, it simply appears to wait.
but:
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("beep ");
}
}, 1, 5, TimeUnit.SECONDS);
produces:
beep beep beep beep beep
at 5 second intervals.
It seems like there is some kind of lock happening here that I cannot determine.
Because you're kind of abusing FutureTask
.
A FutureTask is "a cancellable asynchronous computation" according to the Javadocs, but more colloquially it wraps a particular execution of Runnable/Callable to provide the asynchronicity. I didn't actually realise that it implemented Runnable
until I checked just now - the implementation of run()
"sets this Future to the result of its computation".
So what's happening in your first example is that you're scheduling the future task, its run method gets called after 1 second and so it calculates the result of the computation (i.e. runs the embedded Runnable
). When this method exits, the FutureTask has now run and has its concrete result - so future invocations of run() are no-ops.
I think the root problem here is that it doesn't seem to make sense to schedule a FutureTask directly, at least not in the manner you're doing here. If you want a bit of code to run every five seconds, then you should definitely take the second approach. The FutureTask embodies a (single!) calculation; there's no reason why you'd want it to be invoked multiple times and in fact it's specifically caching the result to prevent this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With