When to join threads
Let's say I need to spawn multiple threads to do the work, and continue to the next step only after all of them complete. I will need to tell the main thread to wait. The key point is to use Thread.join() method. For example,
package foo;The output when running this program with 10 threads:
import java.util.Vector;
public class ThreadTest {
private Vector<String> threadNames = new Vector<String>();
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.threadTest(Integer.parseInt(args[0]));
System.out.println(test.threadNames);
}
private void threadTest(int numOfThreads) {
Thread[] threads = new Thread[numOfThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = new foo.ThreadTest.MyThread();
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException ignore) {}
}
}
class MyThread extends Thread {
public void run() {
for (int i = 0; i < 1000000; i++) {
i = i + 0;
}
threadNames.add(getName());
}
}
}
[Thread-1, Thread-3, Thread-0, Thread-5, Thread-7, Thread-6, Thread-9, Thread-2, Thread-8, Thread-4]The order in which the threads are executed is random, which is expected.
Also note that we use two for-loops, the first to create and start each thread, and the second loop to join each thread. If each thread is joined right after start, the effect is these threads are executed sequentially, without the desired concurrency. For example, the following code snippet results in serial execution:
// The following is NOT concurrent:Output:
//
private void threadTest(int numOfThreads) {
Thread[] threads = new Thread[numOfThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = new foo.ThreadTest.MyThread();
threads[i].start();
try {
threads[i].join();
} catch (InterruptedException ignore) {
}
}
}
If we don't use any join at all, threadNames, when printed, may be empty, or partially filled, since the main thread will just move on when it gets the chance. The main thread will still wait, at the very last step, for all threads to complete, before exiting the JVM. The output for running 10 threads may be:
[Thread-0, Thread-1, Thread-2, Thread-3, Thread-4, Thread-5, Thread-6, Thread-7, Thread-8, Thread-9]
[Thread-0, Thread-1, Thread-2, Thread-3]The following is a general-purpose code skeleton for running concurrency test using anonymous Runnable inner-class:
Another version using java.util.concurrent.CountDownLatch: When to join threads with CountDownLatch
Thread[] threads = new Thread[numOfThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
System.out.println("xxx");
}
});
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
}
}
37 comments:
Thanks for the code snippet about thread join. It helped me.
Regards,
Lakshitha Ranasinghe
Thanks dude.It helped me a lot.
Regards,
Anirban Gangopadhyay
Hi buddy,
In your code you have created the threads[i] as instance to which your are assigning new foo.Threadset.Mythread().How??? can you explain this to me....
MyThread is just an inner class inside ThreadTest class. The inner class also access a vector field from the outer class.
I could've written MyThread as a separate class and should work the same way. Of course, then the vector field will need to be publicly accessible.
It really helped
Wouldn't be better to use a CyclicBarrier object?
Wouldn't it be better to use a CyclicBarrier object?
Thanks a lot. It was exactly what I wanted to know.
Do NOT use CyclicBarrier - ever - unless you understand exactly the performance implications of notifyAll and the underlying thread thrashing that results from it. If you have many threads all updating the SAME object, CyclicBarrier would be a disaster. Better to single file them all using join().
Thanks for the code yaar.. i searched lot for joining of threads n finally ur code helped me..
Regards,
Priti..
Thank you very much for the simple yet effective description about thread join... Keep it up!!!
Crystal clear. Good job
Good one, thanks.
One question: isn't it a risk to join the thread only after having it already started? The runnning thread could have been finished at that time.
Very Nice Article..
Joseph
thanks dude ... this code is helpful to me... i was exactly looking for the same code...thanks
thank you for the code. But I have one question:
if you are creating thread in loop, for example 0-iteration, thread created, called join, after this point, as I understand calling thread should be blocked, and we will not created thread on iteration 1? So how can it be, that you are able to step next instruction after join?
Thanks for the code. great time saver!!!
hi good code is their also
see
http://java.pakcarid.com/Cpp.aspx?sub=230&sls=24&topid=32
Just wanted to add some clarification.
Thread t1 = new Thread();
t1.join() means "wait for this thread to die", now the question is who will wait for whom.
In simple terms it means, every java program starts with a main thread, so here this main thread will be blocked or will wait till thread t1 life cycle ends.
Or any statement next to the t1.join() will be executed only after thread t1 dies.
So suppose you want that your 2 or more threads should do some important work and main thread should wait until all your threads complete there life cycle, in that case use join().
never write code like this:
Suppose you have threads t1, t2 and t3
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
In the above case spawning 3 threads is of no use, as t2 will start only after t1 dies, t3 will start only after t2 dies.
Instead code like this:
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
enjoy!
Sabir
have you any idea how to implement join function ??
Thanks! It was useful
Exactly what I needed. You just salvaged my thesis.
Yeah...It's useful .
Thanks!
Regards!
Thank you very much, it is very clear now
Hi,
I have only one objection to this example:
You expect that the threads finish working in the order you use join in:
for example if the third thread is finished but the first is not the third thread will have to wait for the first to be finished because you call the method join in the order
thread0 thread1 until thread 9.
Can you reply to me at this address:alexdraganesc@gmail.com
Hi, we can not put t1.join immediately after t1.start ..you need to start all and then only do join. else main thread waits for t1 to finish first.
@alexdraganesc
You don't understand that it is the main thread which is waiting for ALL child threads to finish! The child-threads aren't "waiting for each other"! Only the main thread (the one which launched the other threads) is waiting.
Therefore it doesn't matter which child thread finishes first, second, third, etc. If a child thread is already finished, join() on that thread just returns without additional waiting.
Hello,
In this example, what would be a good way to have on the one hand Concurrency on the other reversed order of the execution ?
Can two threads play at the same time but finish in some order ?
Thank you in advance.
good post ...
Thanks for the post:)
Thanks.
Thanks! Very useful!
Good one actually..if you dont feel so .....try to understand it again ..
:)
Simple and clear, Thanks.
In order to join threads in Java, order is very important. Here is a good exercise to learn how to join threads in Java
Thanks buddy, It has helped me to learn about threads.
Post a Comment