Reputation:
I'm just starting to look into Futures and the ScheduledExecutorService in Java, and I'm wondering why my Callable isn't running on the schedule I've indicated. In this sample code, the callable runs once, but the app never completes, nor does the task run again, which is what I expected to happen (I'm sure the problem is with my expectation).
Runnables work fine; Callables seem to block forever, but I'm not sure why.... What am I missing?
Thanks!
public class ExecutorExample {
/**
* @param args
* @throws ExecutionException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
FutureTask<ArrayList<String>> ft1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>(){
@Override
public ArrayList<String> call() {
ArrayList<String> stuff = new ArrayList<String>();
for(int i = 0;i<10;i++){
String thing ="Adding " + i + " to result";
stuff.add(thing);
System.out.println(thing);
}
return stuff;
}});
scheduler.scheduleAtFixedRate(ft1, 0, 1, TimeUnit.SECONDS);
System.out.println(ft1.get());
System.out.println(ft1.isDone());
}
}
Upvotes: 6
Views: 5057
Reputation: 269667
The problem is that FutureTask
is used, and as its class documentation says, "Once the computation has completed, the computation cannot be restarted or cancelled."
After the run
method of FutureTask
has been invoked once, subsequent invocations return immediately, without delegating to the task's Callable
instance.
Only a Runnable
can be used as a recurring task, and this doesn't allow passing back a result. Instead, give the Runnable
task a callback that it can invoke at the end of its run
method, to report the results of each execution of the task back to listeners in other threads.
Upvotes: 9