У меня есть код для ExecutorService.
try{
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Callable<String>> taskList = new ArrayList<Callable<String>>(5);
for(int i=1;i<=5;i++){
taskList.add(new SimpleTask());
}
List<Future<String>> list = executor.invokeAll(taskList);
executor.shutdown();
System.out.println(list.get(0).get());
System.out.println("Exit");
}catch(Exception e){
e.printStackTrace();
}
class SimpleTask implements Callable<String> {
@Override
public String call() throws Exception {
return new Date().toString();
}
}
Я хочу знать, что list.get(0).get() будет ждать завершения всех задач?
Как сказал вомбат, нет. Итак, вы спрашиваете, как это сделать, или это отвечает на ваш вопрос?
Я поставил точку останова в call () и пропускаю первую задачу. Затем также ждем завершения всех задач.
Если вы установите точку останова в call(), вам придется пропустить ее пять раз, потому что именно так часто она будет вызываться. Похоже на то, почему он ждет.




Нет, код в том виде, как он есть, не будет ждать завершения каждой задачи. Вызывая list.get(0).get(), вы получаете самый первый дополнительный вызов get() на нем, который блокирует поток в соответствии с документация.
Чтобы дождаться завершения каждого вызываемого объекта, вам нужно перебрать список и посмотреть, все ли выполнено. Конечно, вы можете сделать это, вызывая get() на каждом из них, но тогда вы все время блокируете свой основной поток. Я сам предпочитаю иметь возможность делать что-то, пока я жду выполнения других потоков.
Пример использования потоков Java 8:
// filter if any future is not done yet
while ( list.stream().anyMatch(i->!i.isDone()) )
{
// Do whatever you want parallel to the evaluation of the Future objects
// example
System.err.println( "Not all are done yet." );
}
// process your results
// example:
String[] results = list.stream().map( Main::evalGet ).toArray(String[]::new);
Примечание. priavte static <T> TevalGet(Future<T> fu) - это просто функция-оболочка, которая сохраняет лямбда-выражение в чистоте от обработки исключений и выглядит примерно так:
private static <T> T evalGet( Future<T> fu )
{
T obj = null;
try
{
obj = fu.get();
}
catch ( InterruptedException | ExecutionException e )
{
e.printStackTrace();
}
return obj;
}
См .: stackoverflow.com/questions/34440604/…
Здесь код будет ждать не выполнения оператора list.get(0).get(), а оператора executor.invokeAll(taskList), потому что сам метод invokeAll() будет ожидать усложнения всех потоков.
Чтобы узнать больше Отвечать
Нет, он будет ждать завершения только одного
Future(первого)