Estoy bien con las promesas de JavaScript. Así que quería probar Java Futures (todavía atascado en Java 7). Pero estos futuros de Java no tienen sentido para mí. Aquí hay una versión recortada y modificada de 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) {} 
        }
    }
}

El resultado es:

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

¿Por qué no se ejecutan las salidas del sistema Waiting for FutureTaskX? Esperaría que el hilo principal se repita y salga del sistema Waiting for ... hasta que se resuelvan los futuros.

No estoy interesado en diferentes formas de resolver este problema, solo en el flujo del programa de este código. Gracias.

1
tokosh 5 abr. 2017 a las 17:45

2 respuestas

La mejor respuesta

El código nunca llega a la línea "Waiting for FutureTask1".

Si futureTask1.get no devuelve un valor dentro del tiempo de espera, se lanza un TimeoutException.

La única vez que regresa sin lanzar una excepción, x y s ya no son nulos.

Vea el FutureTask obtiene documentación.

1
user1717259 5 abr. 2017 a las 15:07

Dado que futureTask1.get(100L, TimeUnit.MILLISECONDS) arrojará TimeoutException, para el futureTask1 el tiempo de sueño es 500 milisegundos, futureTask2 tiene el mismo problema.

Tal vez necesite la salida Waiting for FutureTask en la TimeoutException cláusula catch, y sleep en el bloque finally, tal vez como:

try {
...
} catch (TimeoutException e) {
   System.out.println("Waiting for FutureTask");
} finally {
   Thread.sleep(100);
}
1
chengpohi 5 abr. 2017 a las 15:01