How does the Java run () method work?

Multithreading in Java is accomplished by defining run () and calling start ().

Start delegating your own method that starts the thread through operating system routines, and run () is called from this newly created thread.

When starting a stand-alone application, the main thread is created automatically to execute main ().

Now consider this code -

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

This is the conclusion -

 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) 

If the main () method is started through the thread, why doesnโ€™t the (() method start, is displayed at the top of the call hierarchy?

How can I create a main thread without a Runnable implementation?

+8
java multithreading
source share
4 answers

I did not look at the internals of the JVM, but I would suggest that the JVM creates the main thread to run the main method, but launches this main thread, calling its own code directly, without going through the classic Java classes and methods to start the thread.

+4
source share

If the main () method is started through the thread, why doesnโ€™t the (() method start, is displayed at the top of the call hierarchy?

As already mentioned, this is due to the fact that the "main" thread is special. It does not start through the standard mechanisms of the Thread class, but instead through the Java bootstrap code. public static void main(String[] args) always started by the main thread from native code.

Another explanation is that there may actually be a run() method, but the way they build the stack hides it specifically so as not to confuse the user. For example, since you are doing new Thread(new Test()) , then your Test class is actually the target field inside Thread . When the Thread background starts, 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 on the stack, although it seems like it should be there. The run() method will be on the stack if the user overrides it in the Thread superclass. It can be removed by the JDK to improve stack output.

Multithreading in Java is accomplished by defining run () and calling start ().

This is correct, but for posterity, I thought it was important to understand that your code has a problem. Your Test class should not extend Thread , but instead should implement Runnable . It works because Thread implements Runnable .

Or 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 are you still extending Thread and changing the way you start your thread to something like the following. The above Runnable pattern is recommended, as it allows the 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 it important? The current code actually creates Thread objects, but only one of them is start() ed and works like a Thread background. You might have something like the following error:

 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(); 
+7
source share

The main method runs in a separate JVM thread, this is the parent thread of the child thread, so you do not see the child thread at the top of the call hierarchy.

So, in your case, the JVM created a thread that runs 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 a child thread launched by the JVM to run your program.

Since the main method is the starting point for a stand-alone java program, it is the responsibility of the JVM to run in a separate thread, you do not write code for it.

When starting a program by calling the main method, the JVM does not need to be a thread or implement Runnable, this is the standard procedure.

Description from Inside the Java Virtual Machine

The main () method of the application's source class serves as a starting point for this application seed. The starting thread may in turn disable other threads.

In the Java virtual machine, threads are presented in two versions: daemon and non-daemon. A daemon thread is usually a thread used by the virtual machine itself, such as a thread that runs the garbage collection. However, an application can mark any threads it creates as daemon threads. The initial thread of the application - the one that starts with main () - is a thread without a daemon.

The Java application continues to run (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 terminates. If allowed by the protection manager, the application can also cause its own demise by calling exit () of the Runtime or System class.

The call hierarchy is not controlled by you; it is managed by the main thread scheduler.

So, for example, if I run the same code on my machine, this is the output file

 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) 

therefore, when you run your example, the scheduler decided to release the child thread first before the main one.

Adding to @JB Nizet how the program will be called or how the life cycle of the stream will be implemented depends on the underlying OS and hardware, which will and will change.

No implementation details would provide a complete answer; each implementation would be different.

+3
source share

This may be a semantic argument, but the thread and the process are not synonymous.

The process is launched by the operating system and has its own personal code pages (compiled code set). A Thread is launched from internal programs and is first shared by the parent code pages (compiled code set).

That the JVM internally uses Thread to run the main method is a detail of the implementation of the environment, but not a representation of the Java language. If the thread was supposed to report in the frames of the main stack, the architecture of accessing the source code would not be possible, because this main thread would not have a compilation unit (it is internal to the JVM).

0
source share

All Articles