问题
I have a newbie question. I have this code:
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...");
}
}
Which will wait for all threads to complete. If I use Executors
like this:
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...");
}
}
How can I suspend the main thread to wait for all the threads in the executor to finish, i.e the "All threads completed..." should be printed after the all the threads have done their work?
回答1:
executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
System.out.println("Not yet. Still waiting for termination");
}
Use shutdown() + awaitTermination()
combination.
EDIT:
Based on the comment of @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);
NOTE:
invokeAll()
will not return until all the tasks are completed (either by failing or completing successful execution).
回答2:
You shouldn't use executor like this if you want to wait for tasks to finish. What if you don't want/can't shutdown your thread pool executor? This is a more recommended way:
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:
We can use below code to join the thread.
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();
}
回答4:
Try working with thread pool this way.
executor.shutdown();
executor.awaitTermination(MAX_PRIORITY, TimeUnit.HOURS);
回答5:
exec.shutdown();
// Wait until all threads are finish
exec.awaitTermination();
来源:https://stackoverflow.com/questions/20495414/thread-join-equivalent-in-executor