Why do we call the thread object\'s start()
method which in turns calls run()
method, why not we directly call run()
method?
[...] why not we directly call run() method?
The run()
method is just an ordinary method (overridden by you). As with any other ordinary method and calling it directly will cause the current thread to execute run()
.
All magic happens inside start()
. The start()
method will cause the JVM to spawn a new thread and make the newly spawned thread execute run()
.
Runnable
is just an interface. A class implementing Runnable
is nothing special, it just has a run
method.
Thread#start
is a natively implemented method that creates a separate thread and calls Thread
's run
method, executing the code in the new thread.
Thread
implements Runnable
. The code for run
looks like this:
@Override
public void run() {
if (target != null) {
target.run();
}
}
If the Thread
instance was created by passing a Runnable
to the Thread
's constructor, the Runnable
's run
method is called.
Otherwise, classes extending Thread
have to override the run
method in order for start
to work.
Calling run
on Thread
does NOT create a new thread.
It's due to the design of multithreading in Java.
Calling start ()
will start a new Thread and calling run()
method does not start a new Thread.
If you call start()
method on Thread, Java Virtual Machine will call run() method and two threads will run concurrently now - Current Thread and Other Thread or Runnable implementation.
Have a look at source code of start()
method in Thread class
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already
* started.
* @see #run()
* @see #stop()
*/
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
In above code, you can't see invocation to run()
method.
private native void start0()
is responsible for calling run()
method. JVM creates native thread corresponding to java thread and call run()
method.
Refer to this question for source code of native methods:
Where to find source code for java.lang native methods?
If we want, we can call run()
method, but if we call run method it will run as just a normal Java method. Whereas it we call start(
) it, JVM
creates a new thread and run method will be executed on that thread.
start()
and run()
methods are used for running a thread.The run()
method is just an ordinary method, it is overridden by the user and it will be called on the current thread.
The start()
method runs the run()
method indirectly and creates a new thread.
When we use start method then a new thread is created and then code inside the run method will be executed for each new Thread.
Use of start method creates two stack for each thread ,Stack and native stack.
But Run
method call just execute
the code inside the run
method sequentially as run method call does not create different stacks.
Example
import java.util.concurrent.TimeUnit;
public class thread implements Runnable{
/**
* @param args
*/
public static void main(String[] args) {
Thread gg=new Thread(new thread());
Thread gg1=new Thread(new thread());
gg.run();
gg1.start();
/*gg.start();
gg1.start();*/
}
@Override
public void run() {
for(int i=0;i<5;i++)
{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Hello..." + i);
}
}
}