English 中文(简体)
Java是如何运行 () 方法工作的?
原标题:How does Java run() method work?

Java 中的多行是通过定义运行 () 和引用启动 () 完成的。

代表开始使用一种本地方法,通过操作系统例行程序启动线,并在此新生成线中运行()。

当独立应用程序启动时, 主线会自动创建以执行主( ) 。

现在考虑一下这个代码...

public class Test extends Thread {
    public static void main(String[] args) throws Exception {
        new Thread(new Test()).start();
        throw new RuntimeException("Exception from main thread");
    }
    public void run() {
        throw new RuntimeException("Exception from child thread");
    }
}

这是输出 -

java.lang.RuntimeException: Exception from child thread
    at com.Test.run(Test.java:11)
    at java.lang.Thread.run(Thread.java:662)
java.lang.RuntimeException: Exception from main thread
    at com.Test.main(Test.java:8)

如果主() 方法通过线索启动, 为什么不运行( ) 出现在职业等级的顶端?

不执行可耐性,主线怎么会产卵?

最佳回答

我还没有看过JVM的内部, 但我想, JVM 即时将主线用于运行主方法, 但通过直接引用本地代码来运行主线, 而不通过古典 Java 课程和方法来启动线索 。

问题回答

如果主() 方法通过线索启动, 为什么不运行( ) 出现在职业等级的顶端?

正如其他人提到的那样,这是因为“ 主线”是特殊的。 它不是通过标准 < code> Thread 类机制启动的,而是通过 Java 靴套套件代码启动的。 < code> 公共静电无效主线( string[ ] args) 总是由本地代码的主线运行 。

另一个解释是,实际上也许有一种 run () un () ) 方法,但是他们建立书架框架的方式是故意隐藏它,以免混淆用户。例如,既然你正在做一个 new Thread( new Test ()) 类,那么你的 Test 类实际上是 目标 字段。当背景 Thread 启动时,它实际上称为 Thread.run () , 代码中有代码:

public void run() {
    if (target != null) {
        target.run();
    }
}

但我们从未在书架框中看到过 Thread. run () 方法, 尽管似乎应该存在。 run () 方法 放在书架框中, 如果用户在超级类 < code> Thread 中将其压倒的话。 它可以被 JDK 移除, 以改善书架框架输出 。

Java 中的多行是通过定义运行 () 和引用启动 () 完成的。

这是正确的,但对于后代来说,我认为重要的是要认识到您的代码有问题。您的 Test 类应该 not 来扩展 Thread ,但应该执行 Runnable 。因为 Thread 执行 Runnable ,所以有效。因为 Thread 执行

您要么执行 < code> Runnable , 并将您的代码更改为类似 :

public class Test implements Runnable {
    public static void main(String[] args) throws Exception {
        new Thread(new Test()).start();
        throw new RuntimeException("Exception from main thread");
    }
    public void run() {
        throw new RuntimeException("Exception from child thread");
    }
}

或者您仍然扩展 < code> Thread , 并改变您开始线条的方式, 将线条切换为以下类型。 推荐上述 < code> Runnable 模式, 因为它允许您的 < code> 测试 线条在必要时扩展另一类 。

public class Test extends Thread {
    public static void main(String[] args) throws Exception {
        new Test().start();
        throw new RuntimeException("Exception from main thread");
    }
    @Override
    public void run() {
        throw new RuntimeException("Exception from child thread");
    }
}

为什么这很重要? 您当前的代码实际上是 obtiates 2 < code> Thread 对象, 但其中只有一个是 < code> start () , 并且以背景 < code> Thread 运行。 您可以有以下的错误 :

public class Test extends Thread {
    public static void main(String[] args) throws Exception {
        Test test = new Test(); 
        new Thread(test).start();
        // this is not interrupting the background thread
        test.interrupt();

主方法由 JVM 在一个单独的线索中启动, 它是子线的父线, 这就是为什么您在职业等级的顶端看不到子线 。

所以在你的案例中,JVM创建了一条线 开始了你的程序, 同时也扩展了线索。

然后,在您的主要方法中, 您创建了一个新的课程实例, 它被调用开始于它, 这将开始一个新的线条, 这是由 JVM 启动的启动您的程序的线条之子 。

由于主要方法是一个独立的 java 程序的一个起点, 因此JVM 将它以单独的线条启动是它的责任, 您不会为此写入代码 。

使用主方法启动程序时, JVM 不需要它作为线索或执行可运行程序,但这是一个标准程序。

http://www.artima.com/insidejvm/ed2/jvm.html" rel=“nofollow”>Inside Java虚拟机器

The main() method of an application s initial class serves as the starting point for that application s initial thread. The initial thread can in turn fire off other threads.

Inside the Java virtual machine, threads come in two flavors: daemon and non- daemon. A daemon thread is ordinarily a thread used by the virtual machine itself, such as a thread that performs garbage collection. The application, however, can mark any threads it creates as daemon threads. The initial thread of an application--the one that begins at main()--is a non- daemon thread.

A Java application continues to execute (the virtual machine instance continues to live) as long as any non-daemon threads are still running. When all non-daemon threads of a Java application terminate, the virtual machine instance will exit. If permitted by the security manager, the application can also cause its own demise by invoking the exit() method of class Runtime or System.

调用等级不是由您决定的 而是由底线排程器决定的

举例来说,如果我在机器上 使用同样的代码,这就是输出

Exception in thread "main" java.lang.RuntimeException: Exception from main thread
    at TestThread.main(TestThread.java:6)
Exception in thread "Thread-1" java.lang.RuntimeException: Exception from child thread
    at TestThread.run(TestThread.java:9)
    at java.lang.Thread.run(Thread.java:662)

所以当您运行您的示例时, 调度器选择在主线之前先放走子线 。

@JB Nizet 添加到 @JB Nizet, 如何援引程序, 或如何执行线条生命周期,

没有一个单一的实施细节能够提供完整的答案,每项实施将有所不同。

也许这是一个语义论的论点,但线索和进程不是同义词。

程序由操作系统启动, 并拥有自己的私人代码页( 编译代码集 ) 。 从程序内部启动线索, 最初共享其父代码页( 编译代码集 ) 。

JVM 内部使用线索来运行主方法, 是环境的实施细节, 但不是 Java 语言的表示。 如果线索要在 < code> main 堆叠框中报告, 则无法返回源代码位置, 因为主服务线没有编译单位( 这是 JVM 内部的) 。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签