isAlive()返回false

时间:2017-03-30 11:35:20

标签: java multithreading thread-safety

我有一个类MyTunnel,它扩展了Thread类:

public class MyTunnel extends Thread {
    protected Object obj;
    public MyTunnel() {
        super(MyTunnel.class.getName());
        obj = new Object();
        prepare();
    }
    public void prepare() {
        System.out.println("Before starting...");
        start();
        synchronized(obj) {
            try {
                obj.wait(3000);
            } catch (InterruptedException e) {
                System.out.println("Error while waiting thread to start");
            }
        }

        System.out.println("After starting...");
    }

    @Override
    public void run() {
        System.out.println("running...");
    }

}

当我在主线程上运行以下代码时:

System.out.println("Before creating tunnel...");
MyTunnel tunnel = new MyTunnel();
System.out.println("After creating tunnel...");

System.out.println("Is tunnel alive ? " + tunnel.isAlive());

我看到这样的打印出来了:

Before creating tunnel...
Before starting...
running...
After starting...
After creating tunnel...
Is tunnel alive ? false

我的问题是,为什么tunnel.isAlive()返回false(在上次打印输出消息中)?

但如果我将prepare()功能更改为:

public void prepare() {
    System.out.println("Before starting...");
    start();
    System.out.println("After starting...");
}

再次运行代码,tunnel.isAlive()然后返回true。为什么呢?

1 个答案:

答案 0 :(得分:0)

第一种情况:

您当前(" main")线程启动新线程,然后调用obj.wait(3000);导致当前线程等待,超时为3秒。 等待

的新主题

当前线程等待时,执行新线程。它只写"正在运行..."并很快完成。

因此,"主要&#34>线程恢复(3秒后),新线程已经死亡,因此isAlive()返回false

第二种情况:

您当前的(" main")线程启动新线程并继续执行。

新线程可能会也可能不会运行,而主线程只会进行几次System.out.println()次调用。

因此,新线程尚未执行并且新线程仍然存活,因此isAlive()返回true

请注意,可能发生新线程刚刚在第二个场景中启动后执行。因此,即使在第二种情况下isAlive() 可能返回false,但机会低于第一种情况( - >竞争条件)。

P.S。如果你包括任何" heavy"在调用isAlive()之前的第二个场景中进行操作,结果可能是false。请尝试以下方法:

    System.out.println("Before creating tunnel...");
    final MyTunnel tunnel = new MyTunnel();
    System.out.println("After creating tunnel...");

    for (int i = 0; i < 100; ++i) {
        System.out.print("");
    }

    System.out.println("Is tunnel alive ? " + tunnel.isAlive()); // returns false on my machine