Java ExecutorsService отправляет FutureTask получить на Future возвращает NULL - PullRequest
2 голосов
/ 20 апреля 2019

У меня есть этот фрагмент.

    final ExecutorService executor = Executors.newFixedThreadPool(3);
    final Runnable runnable = ()->{System.out.println("Inside runnable run method");};
    final Callable<String>callable = ()->{System.out.println("Inside callable call method");return "callable";};
    final FutureTask<String> futureTask = new FutureTask<>(()->{System.out.println("CallableInFutureTask");},"JOHN");
    final FutureTask f1 = (FutureTask)executor.submit(callable);
    final FutureTask f2 = (FutureTask)executor.submit(futureTask);
    final FutureTask f3 = (FutureTask)executor.submit(runnable);
    System.out.println("f1 = " + f1+" "+f1.isDone()+" "+f1.get());
    System.out.println("FutureTask Reference Object: "+futureTask.isDone()+" "+futureTask.get());
    System.out.println("f2 = "+f2.isDone()+" "+f2.get());
    System.out.println("f3 = " + f3+" "+f3.isDone()+" "+f3.get());        
    executor.shutdown();

Переменные f1 и f3 Future возвращают правильные значения своего метода get, но FutureTask передает его исполнителям, а f2 возвращает ноль. Почему это так? Даже ссылка futureTask возвращает правильное значение «JOHN» для метода get, но почему это так? Может быть, потому что я прохожу FutureTask? Я не понимаю.

Я просто думал, что ссылки f2 и futureTask вернут одно и то же значение. Извините, если этот вопрос прост, большое спасибо.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2019

Когда вы отправляете FutureTask в ExecutorService, он обрабатывается как Runnable, поэтому Future, полученный из метода submit, будет иметь значение null в качестве Runnable экземпляров. не возвращать никакого результата.

Поскольку FutureTask реализует интерфейс Runnable, этот метод ExecutorService называется submit(Runnable task), поэтому Runnable, который вы заключаете в конструкторе FutureTask, фактически передается в ExecutorService и, следовательно, вы получаете ноль при вызове f2.get().

Но когда вы вызываете get() по ссылке FutureTask, вы получаете обратно значение, которое вы указали в качестве второго параметра, когда Runnable завершил его выполнение (когда вы отправили задание ранее в ExecutorService).

Вы также можете проверить это с помощью , не передавая futureTask в ExecutorService, тогда, если вы попытаетесь вызвать get для переменной futureTask, вызов get будет блокироваться бесконечно, так как Runnable не было выполнено.

 // Returning "JOHN" when the supplied Runnable is completed execution.
 System.out.println("FutureTask Reference Object: "+futureTask.isDone()+" "+futureTask.get());

Это согласно документам :

Создает задание FutureTask, которое при запуске выполнит заданное Runnable, и организовать, что get вернет данный результат на успешное завершение.

1 голос
/ 20 апреля 2019

Это правильно с возвратами.f1 имеет возврат, а f2 и f3 - нет.И ноль означает здесь void

...