Ok , I know the two standard ways to create a new thread and run it in Java :
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.
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, (it's a simple runtime polymorphism in play), I don't 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 constructing the thread?
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:
// passed into the constructor and set in the init() method
private Runnable target;
...
// called from native thread code after start() is called
public void run() {
if (target != null) {
target.run();
}
}
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With