Please explain the output of the below code:
If I call th1.run()
, the output is:
EXTENDS RUN>>
RUNNABLE RUN>>
If I call th1.start()
, the output is:
RUNNABLE RUN>>
EXTENDS RUN>>
Why this inconsistency? Please explain.
class ThreadExample extends Thread{
public void run() {
System.out.println("EXTENDS RUN>>");
}
}
class ThreadExampleRunnable imple开发者_开发知识库ments Runnable {
public void run() {
System.out.println("RUNNABLE RUN>>");
}
}
class ThreadExampleMain{
public static void main(String[] args) {
ThreadExample th1 = new ThreadExample();
//th1.start();
th1.run();
ThreadExampleRunnable th2 = new ThreadExampleRunnable();
th2.run();
}
}
The Thread.start()
method starts a new thread, the entry point for this thread is the run()
method. If you call run() directly it will execute in the same thread. Given that calling Thread.start()
will start a new thread of execution, the run()
method may be called after (as in you example) the rest of the main method executes.
Change your main method to call th1.start()
and run repeatedly, you will see that sometimes it outputs:
EXTENDS RUN>>
RUNNABLE RUN >>
and sometimes it outputs:
RUNNABLE RUN >>
EXTENDS RUN>>
depending on how java chooses to schedule your 2 threads.
Check out the java tutorial on this.
When you call th1.run()
you are running the run
method in the current thread, so thus must happen before call to th2.run()
.
When you call th1.start()
you the run
method is being called on a new thread. In this case it is happening after the call to th2.run()
. (In fact, it is theoretically possible that it could happen before the th2.run()
... but current and previous Sun implementations of thread.start()
do not cause the current thread to immediately "yield" to the new thread.)
This illustrates a common mistake with using Java threads. If you want to run stuff on a new thread, you must call thread.start()
. Directly calling thread.run()
is almost always a mistake.
When you call .run()
, the method is called and the code within executed the same as any other method. If you call .start()
on a thread, though, the run()
method will be run in that thread, and not sequentially in the main thread.
So when you call th1.start()
, you have code executing in two threads at once: the main thread will go on to create th2 and then call its run
method, while the th1 thread will call its own run
method. There is no guarantee on the ordering of these, because they're executing in parallel.
executing run()
is synchronous - executing start()
is asynchronous.
The calls to run()
are just a regular synchronous method call, and they happen in that order. Using th1.start()
, a new thread is started - it's now a two horse rase - the two run methods are now executing independently - first one to the finish wins, and there is no guarantee about order.
But if the order is not guaranteed, why does the new Thread print later most of the time? In practice, it takes some time to start a new thread, so by the time it gets started, the other run()
method has already ran. Even on a multi-core machine, where both threads can execute simultaneously, the new thread will typically come last, since the thread-startup involves more work.
精彩评论