Reputation: 4476
I have an example that seems strange to me.
public class Join {
public static void main(String[] args) {
Thread t1 = new Thread(
new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
);
Thread t2 = new Thread(t1);
t1.setName("t1");
t2.setName("t2");
t1.start();
try {t1.join();} catch (InterruptedException ie) {}
t2.start();
}
}
We'll see printed only t1. If we'll comment "t1.join", we'll se the expected output (t1 t2). Why ?
Upvotes: 4
Views: 712
Reputation: 8598
This is because main thread waits for t1
to die when you call t1.join()
.
And when you do this
Thread t2 = new Thread(t1);
you are passing t1
as target object whose run
method is called.
Upvotes: 0
Reputation: 340733
The second thread is created incorrectly:
Thread t2 = new Thread(t1);
I can't support it by documentation, but in the source code of Thread.run()
I see:
if (target != null) {
target.run();
}
Where target
is Runnable
instance. When the Thread
is done, it clears the target
variable:
private void exit() {
//...
target = null;
This means that when the first thread is done (join()
method) it clears the target
and the second thread does nothing. When join()
is removed, both access the same target
of t1
(race condition).
Never create a thread using another thread instance (even though it implements Runnable
). Instead create a separate Runnable
and pass it:
final Runnable run = new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
Thread t1 = new Thread(run, "t1");
Thread t2 = new Thread(run, "t2"); //new Thread(t1, "t2"); is incorrect!
t1.start();
t2.start();
You don't need any join()
s here, by default these are non-daemon threads.
Upvotes: 10
Reputation: 64632
Add before t2.start();
:
System.out.println("t1 is alive: " + t1.isAlive());
If main
thread is waiting for t1
to die then t2.start()
can not run t1
's run
method. Otherwise, without waiting for t1
to die, t2
can run t1
's run
method.
Upvotes: 0