Java线程对象与运行线程

时间:2015-04-23 06:28:53

标签: java multithreading ocpjp java-threads

您好我正在学习并使用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 主

从这个结果我明白,在线程完成它的run方法之后。正在运行的线程进入死状态并且调用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类的哪些方法依赖于运行线程,哪些方法依赖于线程对象。我希望你能理解这个问题。 提前谢谢?

5 个答案:

答案 0 :(得分:2)

你可以在两种方式上做到这一点。它几乎一样。您应该使用简单的

在第一个代码文件中启动该线程
t.start();

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

答案 1 :(得分:2)

t.start()开始线程之后,这个条件:

if (!t.isAlive()) 

是不太可能满足的 - 因为启动线程没有阻止。这就是为什么它只是跳过(因为t.isAlive() == true)并且进一步没有例外。

答案 2 :(得分:2)

在您的第一次尝试中,您从未重新启动该主题:

Map<Rank, Integer>

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

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

<强> P.S。

为了启动一个线程,调用t.start(); t.join();// add this line, it allows thread to complete first if (!t.isAlive()) { t.start(); } 将导致start()的异步调用。如果你打电话给run(),它就不会以线程开始,它将像普通方法调用一样进行同步调用。

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

  

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

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