java - isAlive() 返回假

标签 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。为什么?

最佳答案

第一种情况:

您的当前(“主”)线程启动新线程,然后调用 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/

相关文章:

java - 创建线程,做某事,杀死线程 - 全部在循环内 [JAVA]

java - Objective-C 中 Java ArrayList 的等价物

java - 使用 RxJava 执行多个 Observable

c++ - 如果只有一个线程停止,ptrace 是否可以从多线程进程读取/写入数据?

python - 多处理子流程

c# - 使用锁的正确位置在哪里

ios - 如果我们使用 GCD,我们需要声明一个属性 atomic 吗?

c# - 跨线程操作无效,即使使用 InvokeRequired

java - 将整数数组传递给 java 中的可比对象

java - jshell中的多行粘贴