我有一个 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。为什么?
最佳答案
第一种情况:
您的当前(“主”)线程启动新线程,然后调用 obj.wait(3000);
导致当前线程等待,超时为3秒。 等待的不是新线程!
当当前线程等待时,新线程被执行。它只写“正在运行...”并很快完成。
因此,“主”线程恢复(3 秒后),新线程已经死亡,所以 isAlive()
返回 false
。
第二种情况:
您的当前(“主”)线程启动新线程并继续执行。
新线程可能运行也可能不运行,而主线程只执行一些System.out.println()
调用。
因此,有可能新线程尚未执行且新线程仍处于 Activity 状态,因此 isAlive()
返回 true
。
请注意,在第二种情况下,可能会发生新线程刚启动就执行的情况。因此,即使在第二种情况下 isAlive()
可能 返回 false
,但几率低于第一种情况(-> 竞争条件) .
附言如果您在调用 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
关于java - isAlive() 返回假,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43116737/