How does Java run() method work? How does Java run() method work? multithreading multithreading

How does Java run() method work?


If main() method is launched via a thread why doesn't run() show up at the top of invocation hierarchy?

As others have mentioned, this is because the "main" thread is special. It is not launched through the standard Thread class mechanisms but instead through Java bootstrap code. The public static void main(String[] args) is always run by the main thread from native code.

Another explanation is that there actually maybe a run() method but the way they build the stackframe is hiding it on purpose for the sake of not confusing the user. For example, since you are doing a new Thread(new Test()) then your Test class is actually the target field inside of the Thread. When the background Thread is started then it actually calls Thread.run() which has the code:

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

But we never see the Thread.run() method in the stackframe although it seems like it should be there. The run() method would be in the stackframe if the user overrode it in a Thread superclass. It could be removed by the JDK to improve stackframe output.

Multi-threading in Java is done by defining run() and invoking start().

This is correct but for posterity I thought it was important to realize that your code has a problem. Your Test class should not be extending Thread but instead should be implementing Runnable. It works because Thread implements Runnable.

Either you should implement Runnable and change your code to something like this:

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");    }}

Or you still extend Thread and change the way you start your thread to something like the following. The above Runnable pattern is recommended since it allows your Test thread to extend another class if necessary.

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");    }}

Why is this important? You current code is actually instantiates 2 Thread objects but only one of them is start()ed and is running as a background Thread. You could have something like the following bug:

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();


I haven't looked at the internals of the JVM, but I would guess that the JVM instantiates the main thread to run the main method, but runs this main thread by invoking native code directly, without going through the classical Java classes and methods to start the thread.


main method is started in a separate thread by JVM, it is the parent thread of child thread, thats why you dont see child thread at the top of invocation hierarchy.

So in your case JVM created a thread started your program, which also extends Thread.

Then in your main method you created a new instance of your class, called start on it, this will start a new thread which is child of thread started by JVM to launch your program.

Since main method is a starting point for a standalone java program, it is the responsiblity of JVM to launch it in a separate thread, you dont write code for it.

While launching a program by calling main method JVM doesn't need it to be a Thread or implement Runnable, it is a standard procedure.

Description from Inside Java Virtual Machine

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.

The call hierarchy is not governed by you it is governed by the underlying thread scheduler.

So for example If I run the same code on my machine this is the output

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)

so when you ran your example, scheduler choose to let go child thread first before main.

Adding to @JB Nizet, how a program will be invoked, or how a thread lifecycle will be implemented depends from underlying OS and hardware, which will and does vary.

No single implementation details would provide a complete answer, each implementation will vary.