Reputation: 105
I am trying to create a deadlock using join in threads (JAVA). According to my understanding the below program should terminate. Can somebody please explain why the below program doesn't terminate?
public class DeadLockUsingJoins2 {
public static void main(String[] args) {
AThread a = new AThread(null, "A");
a.start();
AThread b = new AThread(a, "B");
b.start();
a.t = b;
}
}
class AThread extends Thread{
public Thread t;
public AThread(Thread thread, String name){
super(name);
this.t = thread;
}
@Override
public void run(){
try {
if(t != null)
t.join();
else
{
Thread.sleep(5000);
}
// if(t != null)
// t.join();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("Somebody interruped thread - " + this.getName());
}
System.out.println("Winding Up thread - " + this.getName());
}
}
Upvotes: 3
Views: 998
Reputation: 136162
add a pause before a.t = b;
b.start();
Thread.sleep(100);
a.t = b;
it will work. But to be reliable it needs syncronization, eg like this
public class DeadLockUsingJoins2 {
public static boolean go;
public synchronized static void main(String[] args)
throws InterruptedException {
AThread a = new AThread(null, "A");
AThread b = new AThread(a, "B");
a.start();
while (!go) {
DeadLockUsingJoins2.class.wait();
}
a.t = b;
b.start();
DeadLockUsingJoins2.class.notifyAll();
}
}
class AThread extends Thread {
public Thread t;
public AThread(Thread thread, String name) {
super(name);
this.t = thread;
}
@Override
public void run() {
try {
if (t != null)
t.join();
else {
synchronized (DeadLockUsingJoins2.class) {
DeadLockUsingJoins2.go = true;
DeadLockUsingJoins2.class.notifyAll();
}
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Winding Up thread - " + this.getName());
}
Upvotes: 2
Reputation: 2644
The only reason i see for not terminating is that your main thread reaches the line
a.t = b;
before thread "a" reaches the lines
if(t != null)
t.join();
if so, the threads wait for each other to terminate.
To make sure you get a deadlock - your class names suggests this - you should reorder your main method:
public static void main(String[] args) {
AThread a = new AThread(null, "A");
AThread b = new AThread(a, "B");
a.t = b;
a.start();
b.start();
}
Upvotes: 3
Reputation: 5291
It will deadlock if main thread is executed up to a.t = b;
before run()
on any of the created threads is actually called. The threads then deadlock on join()
calls.
EDIT: To avoid this, you need to use some sort of synchronization between the main thread and the threads you're creating. For example, signal the start of run()
using Object.notify()
and wait for that using Object.wait()
in main thread.
Upvotes: 2
Reputation: 15250
Most of the time it terminates. The problem appears when thread B starts running (but doesn't pass the if(t != null)
check) after making a.t = b
.
When this is the case both threads waits one for the other to finish because of the join
inside.
Upvotes: 1
Reputation: 1552
So you have successfully written a deadlock, because each of your threads is waiting for the other.
Because the thread run method never finish.
Upvotes: 1