Reputation: 1258
I have a few calculations that I'm spawning off into new threads then when all these calculations are complete I want to continue my execution.
Here's some mock up code that is similar to what I want to achieve without all the specifics,
public void calculation1(){
Thread thread = new Thread(){
public void run(){
/* do calculation */
};
};
}
public void calculation2(){
Thread thread = new Thread(){
public void run(){
/* do some other calculation */
};
};
}
calculation1();
calculation2();
/* Wait here until calculation1() and calculation2() complete */
/* Continue execution */
What's the best way for me to do this??
Upvotes: 0
Views: 157
Reputation: 4637
You can call join
method on your thread with this call no other thread can execute until this thread completes its execution refer join method doc, I have written a sample code, in your case Thread1 can be from calculation1 and Thread2 can be in calculation2 method.
Thread thread1 = new Thread()
{
@Override
public void run()
{
System.out.println("thread1 is running from method calculation1");
try
{
Thread.sleep(10000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
};
thread1.start();
try
{
thread1.join();
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
Thread thread2 = new Thread()
{
@Override
public void run()
{
System.out.println("thread2 is running from method calculation2");
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
};
thread2.start();
try
{
thread2.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//now here if you have more threads then that will not start until thread 1 and thread 2 are completed
Upvotes: 0
Reputation: 424973
Use the Executor
framework to submit Future
tasks, which will all return in the same time as the longest single task. In its simplest form, this would work:
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> future1 = executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
return someValue;
}
});
Future<Object> future2 = executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
return someOtherValue;
}
});
Object result1 = future1.get();
Object result2 = future2.get();
Future.get()
is a blocking call, which returns as soon as the Callable
returns, but returns immediately if the Callable
has already finished, so you will have both result1
and result2
in the time it takes the longest one to run.
Remember to submit()
them all before making the first call to get()
.
Also, if you do use Threads
directly, don't extend Thread
(unless you're creating a new kind of Thread
, which you're not): Instead, pass a Runnable
to the Thread
constructor and start()
the Thread
.
Upvotes: 2
Reputation: 1913
Check out the join() method on the Thread class - http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#join%28%29
Something like this:
public Thread calculation1(){
Thread thread = new Thread(){
public void run(){
/* do calculation */
}
};
thread.start();
return thread;
}
public Thread calculation2(){
Thread thread = new Thread(){
public void run(){
/* do some other calculation */
};
};
thread.start();
return thread;
}
And then use isAlive() and join() to wait for execution to finish
List<Thread> threads = new ArrayList<Thread>();
threads.add(calculation1());
threads.add(calculation2());
for(Thread t : threads){
if(t.isAlive()){
t.join();
}
}
Upvotes: 3
Reputation: 2453
You can use CountDownLatch
. Following is the sample program:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class MyMaster {
public static void main(String[] args) {
CountDownLatch waitForSlavesToComplete = new CountDownLatch(2);
new Thread(new MySlave1(waitForSlavesToComplete)).start();
new Thread(new MySlave2(waitForSlavesToComplete)).start();
// Wait for all slave threads to complete
try {
waitForSlavesToComplete.await(900, TimeUnit.SECONDS);
} catch(InterruptedException e) {e.printStackTrace();}
}
}
public class MySlave1 extends Thread {
CountDownLatch latch = null;
public MySlave1(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
//Perform slave specific operations
try {
this.latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MySlave2 extends Thread {
CountDownLatch latch = null;
public MySlave2(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
//Perform slave specific operations
try {
this.latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Upvotes: 0