我正在尝试使用线程中的连接(JAVA)创建死锁。根据我的理解,下面的程序应该终止。有人可以解释为什么下面的程序没有终止?
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());
}
}
答案 0 :(得分:3)
我看到没有终止的唯一原因是你的主线程到达
行a.t = b;
在线程“a”到达行之前
if(t != null)
t.join();
如果是,则线程等待彼此终止。
为了确保您遇到僵局 - 您的班级名称暗示了这一点 - 您应该重新排序主要方法:
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();
}
答案 1 :(得分:2)
如果在实际调用任何创建的线程上a.t = b;
之前主线程执行到run()
,它将会死锁。然后线程在join()
次调用时死锁。
编辑:为了避免这种情况,您需要在主线程和您正在创建的线程之间使用某种同步。例如,使用run()
发信号通知Object.notify()
,并在主线程中使用Object.wait()
等待。{/ p>
答案 2 :(得分:2)
在a.t = b;
之前添加暂停 b.start();
Thread.sleep(100);
a.t = b;
它会起作用。但要可靠,它需要同步,例如像这样
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());
}
答案 3 :(得分:1)
所以你已经成功写了一个死锁,因为你的每个线程都在等待另一个。
因为线程运行方法永远不会完成。
答案 4 :(得分:1)
大部分时间终止。在创建if(t != null)
后,线程B开始运行(但未通过a.t = b
检查)时会出现问题。
在这种情况下,由于内部join
,两个线程都会等待另一个线程完成另一个线程。