views:

265

answers:

5

Ok , I know the two standard ways to create a new thread and run it in Java :

1 Implement Runnable in a class , define run method ,and pass an instance of the class to a new Thread. When the start method on the thread instance is called , the run method of the class instance will be invoked.

2 Let the class derive from Thread, so it can to override the method run() and then when a new instance's start method is called , the call is routed to overridden method.

In both methods , basically a new Thread object is created and its start method invoked. However , while in the second method , the mechanism of the call being routed to the user defined run() method is very clear ,( its a simple runtime polymorphism in play ), I dont understand how the call to start method on the Thread object gets routed to run() method of the class implementing Runnable interface. Does the Thread class have an private field of Type Runnable which it checks first , and if it is set then invokes the run method if it set to an object ? that would be a strange mechanism IMO.

How does the call to start() on a thread get routed to the run method of the Runnable interface implemented by the class whose object is passed as a parameter when contructing the thread ?

+5  A: 

The Thread keeps a reference to the Runnable instance, and calls it in the base implementation of run.

You can see this in the source

SLaks
Presumably this will often be a reference to `this` as in the 2nd method?
Finbarr
This does not answer his question. If you derive from Thread, the Runnable reference, called target in the source, is null.
Frederik Wordenskjold
@Frederik: Yes, but since you overrode `run`, nothing will happen to it.
SLaks
Why was this downvoted?
SLaks
Exactly. But I just found you answer easy to misunderstand, because you dont mention this directly. Ohh and just fyi, I did not downvote you.EDIT: Sorry. I was the one misunderstanding the OP's question!
Frederik Wordenskjold
Accepted as answer, but looks like this would mean it is based on a very empirical algorithm . If the object happens to be a derived class of Thread, the override will be invoked. else the default , which will check for a reference to be set or not and invoke run() ...am thinking why they did it this way..is this any pattern ?
Bhaskar
+1  A: 

In both the cases there has to be concrete Thread class. In the first case (implementing a Runnable), makes the class that implements it capable of 'being' a thread. You still have to pass your class as an argument to the constructor of the Thread class. Whereas thats not the scenario in the second case where you extend a Thread Class.

When a start() method is called, there is no guarantee that the run() method will be immediately invoked. Calling a start() method tells that the thread is ready to run. It can go to any of the states thereafter depending on the Thread pooler.

FYI : class Thread implements Runnable

Bragboy
+1  A: 

You could have just checked the source of Thread.java included as part of the JDK:

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

where target is:

private Runnable target;

But I think the real answer you are looking for is the details on how threads really work. That is unfortunately abstracted away in native libraries. Just try to get a high level understanding of how threading works.

Pyrolistical
+1  A: 

While you can look at the actual source code, at a guess it would be something like:

public class MyThread implements Runnable {
 private  Runnable r;
 public MyThread() {
 }
 public MyThread(Runnable r) {
        this.r = r;
 }

 public void start() {
   //magic to launch a new thread
   run(); // the above magic would probably call run(), rather than
          // call it directly here though.
  }
  public void run() {
    if(r != null) 
       r.run();
   }
}

In short, if you extend MyThread and override run(), your run() method would be called. If you passed a Runnable instead, the run() method of MyThread would just delegate to the run() method of that Runnable.

nos
sadly *insert magic here* is the simplest explanation
Pyrolistical
Your guess is completely correct, except that `r` is called `target`, and that the constructor calls an `init` method that sets it.
SLaks
A: 

The one thing that's not yet been explored by the answers is how things get from start() to run(), which is simultaneously both simple and complex.

In simplistic terms, the start() method calls a native method (start0 in the OpenJDK implementation) which allocates some memory for a new stack and asks the OS to run a thread with that space as stack and with a plain C++ function (thread_entry in the OpenJDK implementation) as implementation function. That function in turn does the thunk back into Java to call the run() method on the Thread object. The pattern at the low level (asking the OS to start a new thread on a stack and with a function) should be familiar to anyone doing native threads in either POSIX systems or Windows.

The detail makes it all a lot more complex, with all the error handling and obscure edge cases that need to be handled. If you're curious, read the OpenJDK sources, paying particular attention to Thread.java, JVM_StartThread in jvm.cpp and the JavaThread class in thread.cpp and thread.hpp. Hopefully this answer gives you enough detail for you to find your own way...

Donal Fellows