Reputation: 307
I am starting these threads:
ThreadingHDFSUsage HDFSUsage=new ThreadingHDFSUsage(dcaps);
ThreadingRAMandContainers RAMandContainers=new ThreadingRAMandContainers(dcaps);
ThreadingCoreNodesHDFSUsage CoreNodesHDFSUsage=new ThreadingCoreNodesHDFSUsage(dcaps);
ThreadingApplicationMonitoring ApplicationMonitoring= new ThreadingApplicationMonitoring(dcaps);
How should i wait for all these threads to complete before doing some other operation.
My sample thread class code for one thread operation is:
public class ThreadingHDFSUsage extends Thread {
//private PhantomJSDriver driver;
private DesiredCapabilities dcaps;
public ThreadingHDFSUsage(DesiredCapabilities dcaps) {
// TODO Auto-generated constructor stub
this.dcaps = dcaps;
}
public void run(){
System.out.println("task HDFS Usage");
PhantomJSDriver driver = new PhantomJSDriver(dcaps);
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(".........HDFS Usage..........");
String OverallHDFSUsage[] = null;
try {
OverallHDFSUsage = HDFSUsage.getWebData(driver,"http://1.2.3.4:8888/dfshealth.html#tab-overview","//*[@id=\"tab-overview\"]/table[2]/tbody/tr[2]/td","");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String OverallHDFSUsage1 = OverallHDFSUsage[0];
}
}
Similarly, I have relevant code for other threads.
So, how do i wait for all these 4 thread operation to complete?
Upvotes: 2
Views: 204
Reputation: 4569
Both of the other answers are correct, but for completeness, there's yet another way to do what you want using a Semaphore
. This method won't yield results different from any of the other answers, but may be faster if any of your threads have to do something expensive after the results you want are obtained, prior to returning. Inside each of your threads, call s.release()
as soon as all pertinent work is finished. Your controller thread might look like this ...
Semaphore s = new Semaphore(0);
//start all four of your threads here and pass 's' to each
s.acquire(4);
... and your worker threads might look like this:
@Override
public void run(){
//compute results
s.release(1);
//do expensive cleanup and return
}
Upvotes: 0
Reputation: 11996
There's also CompletionService
in JDK concurrent
package. To use it, you switch from explicit Threads
to tasks, represented as instances of Callable<ResultType>
or Runnable
. While code may look slightly more complicated, it is quite convenient, once you became used to it:
import java.util.concurrent.*;
class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletionService<String> completionService = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
completionService.submit(() -> {
Thread.sleep(5000);
return "sleeped for 5000 millis";
});
completionService.submit(() -> {
Thread.sleep(1000);
return "sleeped for 1000 millis";
});
// etc
System.out.println("Completed: " + completionService.take().get());
System.out.println("Completed: " + completionService.take().get());
}
}
Upvotes: 0
Reputation: 2614
Just join() them again:
HDFSUsage.join();
RAMandContainers.join();
CoreNodesHDFSUsage.join();
ApplicationMonitoring.join();
Each join() waits for the specific thread to finish.
Upvotes: 2