Which method calls run()?
Asked Answered
F

1

4
public class HelloRunnable implements Runnable {

public void run() {
    System.out.println("Hello from a thread!");
}

public static void main(String args[]) {
    (new Thread(new HelloRunnable())).start();
} } 

According to Java Doc

The Runnable interface defines a single method, run, meant to contain the code executed in the thread. The Runnable object is passed to the Thread constructor.

So, When we execute HelloRunnable, who calls the inside run method? In the Thread class, the start method looks like this:

public synchronized void start() {
     if (threadStatus != 0)
         throw new IllegalThreadStateException();
     group.add(this);
     start0();
     if (stopBeforeStart) {
         stop0(throwableFromStop);
     }
 }

From this code, we can see that the start method is not calling the run() method.

Fitz answered 29/8, 2016 at 11:53 Comment(5)
What about start0 method, does it call run method? I mean, there's no magic, right? If run gets called, someone must be calling it :-)Cainozoic
what is threadstatus? stopBeforeStart?Resolvable
@dasblinkenlight start0() looks like this.. inline ` private native void More ...start0();`Fitz
@dasblinkenlight, A thread's run() method is not called from anywhere inside the start() call. If thread A calls t.start(), you wouldn't want t.run() to be called by thread A would you? You'd want it to be called by a different thread. But, the t.start() call happens in thread A, and everything that is directly or indirectly called by t.start() happens in thread A. The t.run() method gets called from somewhere else.Unamerican
@dasblinkenlight, P.S., If "magic" means "something you can't accomplish by writing pure Java code," then yes. There is magic. As far as a pure Java programmer is concerned, system calls are magic.Unamerican
C
19

It is stated right in the documentation of start:

the Java Virtual Machine calls the run method of this thread

So, it is the native code in start0 of the JVM that takes care of calling run in the newly created thread. (This is not quite unexpected, as launching a thread is very OS-specific and cannot be implemented in pure Java.)

Note: start0 does not call run directly. Instead (on a high-level view, ignoring JVM-internal management), it instructs the operating system to create a new thread and let that thread execute run.

Just to clarify, here is a short description of the involved methods:

  • start is the high-level function to start a new Thread.

  • start0 is the native method which creates a new Thread from the operating system and is responsible to ensure that run is called.

  • run is the method defined in your Runnable classes. This method is what will be executed in the new thread. A Thread object in Java itself has no idea about the user code it should execute. This is the responsibility of the associated Runnable object.

Thus, when you call Thread.start(), the run method of the Runnable will automatically be called.

Of course, you can always call the run method of a Runnable explicitly:

HelloRunnable hr = new HelloRunnable();
hr.run();

However, this will, of course, not be executed in a separate thread, but block the execution.

Christiniachristis answered 29/8, 2016 at 11:57 Comment(3)
Then when does JVM comes into the picture, like how JVM gets notified that start() has been called and now it is time to call the run() method? @martinFitz
Ok, Thanks. (Just curious) So is it possible to call the run() (pure java code) from the native code?Fitz
I notice that you are careful to say that start0 "takes care of calling" run(), but you could be more explicit about the fact that it does not call run(). In fact, run() is not called from anywhere within the start() call. It's called in a different thread. That's a concept that a lot of noobs have trouble grasping.Unamerican

© 2022 - 2024 — McMap. All rights reserved.