【问题标题】:Java Thread object vs Running ThreadJava 线程对象与运行线程
【发布时间】:2025-12-22 17:45:17
【问题描述】:

嗨,我正在学习和玩 Java 中的线程。我在一本书中读到 Thread 对象和 Running Thread 不是一回事。即使线程完成它的 run 方法运行线程进入死状态我什至用 isAlive() 方法检查。我想知道,如果两者不同,那么按照我的理解,以下代码无法正常工作。

public class Main {

    public static void main(String[] args) throws ParseException {
        Student s = new Student();

        Thread t = new Thread(s);

        t.start();
        t.run();
        t.run();
        t.run();

        t.run();
        t.run();

    }
}

class Student implements Runnable {
    public void run() {

        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

它只显示这个输出。 主要的 线程-0 主要的 或这个 线程-0 主要的

从这个结果我了解到线程完成后它的运行方法。运行线程进入死态并调用 Thread obj 方法不起作用。但我无法理解背后的原因,因为 Thread 对象是技能参考,而 Thread 类的其他方法呢。 喜欢 屈服()? 开始()?

这里是另一个场景,可以清楚地理解我所说的

public class Main {

    public static void main(String[] args) throws ParseException {
        Student s = new Student();

        Thread t = new Thread(s);

        t.start();

        if (!t.isAlive()) {

            t.start();
        }

    }
}

class Student implements Runnable {
    public void run() {

        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

文档说如果我们在 Thread t 对象上调用 start 方法,那么它将抛出 java.lang.IllegalThreadStateException。但上面的代码工作正常。 我对 Thread 类的哪些方法依赖于运行线程以及哪些方法依赖于线程对象感到非常困惑。我希望你明白这个问题。 提前谢谢?

【问题讨论】:

    标签: java multithreading ocpjp java-threads


    【解决方案1】:

    t.start()启动线程之后,这个条件:

    if (!t.isAlive()) 
    

    veeeeeeeeeeeeeeeeeee 不太可能被满足——因为启动的线程不会阻塞。这就是为什么它只是跳过(因为t.isAlive() == true)并且毫无例外地走得更远。

    【讨论】:

    • 我知道大多数时候它不会发生。但是为什么 run 和其他方法仍然不能作为我的第一个代码工作
    • 因为t 已经在t.start() 的第一次调用中消耗了Runnable s,它是用它创建的。
    • "如果这个线程是使用单独的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法什么都不做并返回。"--@ 987654321@
    • 你能详细说明一下吗
    【解决方案2】:

    这两种方式都可以。这几乎是一样的。你应该在你的第一个代码文件中启动线程,只需一个简单的

    t.start();
    

    我会从您上面的代码中删除所有t.run(),因为您正在使用您实现的内部类创建一个新的Thread 对象。

    【讨论】:

    • 实现内部类 Student 类的第一件事是单独的类。其次,我多次调用 run 方法来了解为什么这个方法没有调用的区别,因为它只是驻留在堆上的简单对象,它仍然引用和反对幕后故事。
    【解决方案3】:

    在您的第一次尝试中,您从未重新启动线程:

    t.start();
    t.run();// does not restarts the thread, it simply makes synchronous call the run(), hence you don't get the exception
    t.start();// add this line, to restart the thread and get the exception
    

    在第二次尝试时,条件失败,因为线程可能已启动并且处于活动状态,因为您的条件线程不能处于活动状态并且无法重新启动线程。

    t.start();
    t.join();// add this line, it allows thread to complete first
    if (!t.isAlive()) {
        t.start();
    }
    

    附言

    为了启动线程调用start(),这将导致异步调用run()。如果你调用run(),它不会作为线程启动,它会像普通方法调用一样是同步调用。

    【讨论】:

    • ok Arvind 我明白了,但我还不明白它为什么会发生。因为我使用扩展线程类的启动线程运行它,所以我多次调用 run 方法并且它有效。
    • @artaxerxe,请仔细阅读OP帖子,OP在问为什么没有运行时错误?
    • @Arvind 我认为 runtime error 指的是第二个帖子。但无论如何,您更新的评论澄清了这个问题。谢谢:)。
    【解决方案4】:

    在您提供的第一个示例中,程序未显示等于您的t.start() + t.run() 调用的线程名称计数的原因是线程死后,您无法调用它@987654323 @ 或 run() 再次。它死了。有 3 个输出的原因可能是因为直到 t.start() 进入死状态,其他 2 个调用才能执行。

    在第二个示例中,您应该知道,当调用 start() 时,线程状态会处于活动状态。无论如何,在并发环境中,如果不涉及synchronized,则不能依赖操作调用顺序,但是,从您得到的结果来看,似乎t.start()t.isAlive() 检查之前被调用。 希望有所帮助。

    【讨论】:

    • 如果我在线程死后从线程类扩展怎么样。它的运行方法工作
    • @T.Malik 您不能从对象扩展。你从一个类扩展。如果我没有理解正确,请更准确。
    【解决方案5】:

    我在一本书中读到 Thread 对象和 Running Thread 不是一回事。

    没错,“线程”是代码的执行。 Thread 是一个 Java 对象,您可以使用它来创建和管理“线程”的生命周期。在调用Thread 对象的.start() 方法之前,不会创建“线程”,即使在“线程”完成工作并消失后,Thread 对象也可以继续存在。

    【讨论】: