Java程序不会终止

时间:2013-04-11 09:14:10

标签: java concurrency

我正在尝试使用线程中的连接(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());
    }

}

5 个答案:

答案 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,两个线程都会等待另一个线程完成另一个线程。