1

嗨,我正在学习和玩 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();
        }

    }

}

它只显示这个输出。main Thread-0 main 或这个 Thread-0 main

从这个结果我了解到线程完成后它的运行方法。运行线程进入死态并调用 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 类的哪些方法依赖于运行线程以及哪些方法依赖于线程对象感到非常困惑。我希望你明白这个问题。提前致谢?

4

5 回答 5

2

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

t.start();

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

于 2015-04-23T06:40:29.823 回答
2

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

if (!t.isAlive()) 

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

于 2015-04-23T06:40:45.487 回答
2

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

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(),它不会作为线程启动,它将像普通方法调用一样是同步调用。

于 2015-04-23T06:42:20.173 回答
1

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

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

于 2015-04-23T08:00:24.600 回答
0

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

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

于 2015-04-23T13:27:30.423 回答