marc
marc

Reputation:

Seeking Clarity on Java ScheduledExecutorService and FutureTask

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

Answers (1)

erickson
erickson

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

Related Questions