1

I am fine with javascript promises. So I wanted to try out Java Futures (still stuck in java 7). But these Java Futures don't make sense to me. Here is a trimmed and modified version of journaldev:

import java.util.concurrent.*;

public class FutureTest {
    static class MyCallable implements Callable<String> {
        private long waitTime;
        MyCallable(int timeInMillis){
            this.waitTime=timeInMillis;
        }
        @Override
        public String call() throws Exception {
            Thread.sleep(waitTime);
            return Thread.currentThread().getName();
        }
    }

    public static void main(String[] args) throws Exception {
        MyCallable callable1 = new MyCallable(500);
        MyCallable callable2 = new MyCallable(1000);
        FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
        FutureTask<String> futureTask2 = new FutureTask<String>(callable2);

        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(futureTask2);
        executor.execute(futureTask1);

        while (true) {
            try {
                boolean done1 = futureTask1.isDone();
                boolean done2 = futureTask2.isDone();

                if(futureTask1.isDone() && futureTask2.isDone()){
                    System.out.println("Done");
                    executor.shutdown();
                    return;
                }

                System.out.println("Done1:" + done1 + " - 2:" + done2);

                String x = futureTask1.get(100L, TimeUnit.MILLISECONDS);
                if (x != null)
                    System.out.println("FutureTask1 output="+x);
                else
                    System.out.println("Waiting for FutureTask1");

                String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
                if(s != null)
                    System.out.println("FutureTask2 output="+s);
                else
                    System.out.println("Waiting for FutureTask2");

                Thread.sleep(100);
            } catch(TimeoutException e) {} 
        }
    }
}

The output of it is:

Done1:false - 2:false
Done1:false - 2:false
Done1:false - 2:false
Done1:false - 2:false
Done1:false - 2:false
FutureTask1 output=pool-1-thread-2
Done1:true - 2:false
FutureTask1 output=pool-1-thread-2
Done1:true - 2:false
FutureTask1 output=pool-1-thread-2
FutureTask2 output=pool-1-thread-1
Done

Why are the Waiting for FutureTaskX System-outs not executed? I would expect the main thread to loop and System-out Waiting for ... until the Futures are resolved.

I'm not interested in different ways of solving this problem, only in the program flow of this code. Thanks.

tokosh
  • 1,772
  • 3
  • 20
  • 37
  • 1
    *Please* get in the habit of using braces even for one-line blocks. It will save you lots of mistakes, and is easier for the rest of us to read. – slim Apr 05 '17 at 15:47

2 Answers2

1

The code never reaches the "Waiting for FutureTask1" line.

If futureTask1.get does not return a value within the timeout, a TimeoutException is thrown.

The only time that it returns without throwing an exception, x and s are no longer null.

See the FutureTask get documentation.

user1717259
  • 2,717
  • 6
  • 30
  • 44
1

Since futureTask1.get(100L, TimeUnit.MILLISECONDS) will throw TimeoutException, for the futureTask1 sleep time is 500 millseconds, futureTask2 has the same issue.

Maybe you need output Waiting for FutureTask in TimeoutException catch clause, and sleep in finally block, maybe like:

try {
...
} catch (TimeoutException e) {
   System.out.println("Waiting for FutureTask");
} finally {
   Thread.sleep(100);
}
chengpohi
  • 14,064
  • 1
  • 24
  • 42