Thread.join() эквивалент в исполнителе
У меня вопрос новичков. У меня есть этот код:
public class Main
{
public static void main(String[] args) throws InterruptedException
{
// TODO Auto-generated method stub
IntHolder aHolder=new IntHolder();
aHolder.Number=0;
IncrementorThread A= new IncrementorThread(1, aHolder);
IncrementorThread B= new IncrementorThread(2, aHolder);
IncrementorThread C= new IncrementorThread(3, aHolder);
A.start();
B.start();
C.start();
A.join();
B.join();
C.join();
System.out.println("All threads completed...");
}
}
Которая будет ждать завершения всех потоков. Если я использую Executors
следующим образом:
public class Main
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
IntHolder aHolder=new IntHolder();
aHolder.number=0;
IncrementalRunable A= new IncrementalRunable(1, aHolder);
IncrementalRunable B= new IncrementalRunable(2, aHolder);
IncrementalRunable C= new IncrementalRunable(3, aHolder);
ExecutorService exec = Executors.newFixedThreadPool(3);
exec.execute(A);
exec.execute(B);
exec.execute(C);
//Don't know what to do here
System.out.println("All threads completed...");
}
}
Как приостановить основной поток, чтобы дождаться завершения всех потоков в исполнителе, т.е. "Все потоки завершены..." должны быть напечатаны после того, как все потоки выполнили свою работу?
Ответы
Ответ 1
executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
System.out.println("Not yet. Still waiting for termination");
}
Используйте комбинацию shutdown() + awaitTermination()
.
EDIT:
Основываясь на комментарии @Lital
List<Callable<Object>> calls = new ArrayList<Callable<Object>>();
calls.add(Executors.callable(new IncrementalRunable(1, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(2, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(3, aHolder)));
List<Future<Object>> futures = executor.invokeAll(calls);
Примечание:
invokeAll()
не будет возвращаться до тех пор, пока все задачи не будут завершены (либо сбой, либо завершение успешного выполнения).
Ответ 2
Вы не должны использовать такой исполнитель, если хотите дождаться завершения задач.
Что делать, если вы не хотите/не можете выключить свой исполнитель пула потоков?
Это более рекомендуемый способ:
ExecutorService exec = Executors.newFixedThreadPool(3);
Collection<Future<?>> tasks = new LinkedList<Future<?>>();
Future<T> future = exec.submit(A);
tasks.add(future);
future = exec.submit(B);
tasks.add(future);
future = exec.submit(C);
tasks.add(future);
// wait for tasks completion
for (Future<?> currTask : tasks) {
try {
currTask.get();
} catch (Throwable thrown) {
Logger.error(thrown, "Error while waiting for thread completion");
}
}
Ответ 3
Попробуйте работать с пулом потоков таким образом.
executor.shutdown();
executor.awaitTermination(MAX_PRIORITY, TimeUnit.HOURS);
Ответ 4
Мы можем использовать приведенный ниже код, чтобы присоединиться к ветке.
executor.execute(new YouThread());
try{
executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
System.out.println("Not yet. Still waiting for termination");
}
}catch(InterruptedException e){
e.printStackTrace();
}
Ответ 5
exec.shutdown();
// Wait until all threads are finish
exec.awaitTermination();