Please explain the output from Thread run() and start() methods - java

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 implements 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.

Related

All methods in runnable class run on a seperate thread or only run() method? Java

Let's say I have a runnable class with two methods:
class ExampleClass implements Runnable {
public void shutdown()
{
currentThread().interrupt();
}
public void run(){
while(!currentThread().isInterrupted()){
System.out.println("thread is running...");
}
}
And I go and implement the class somewhere like so and pass it to a thread:
ExampleClass object = new ExampleClass();
Thread sideThread = new Thread( object, "Side Thread");
thread.start();
object.shutdown();
Will all this object and all its methods be running on sideThread or is just the run() method of object on the side thread?
i.e. When I call shutdown() will it actually interrupt the sideThread or will it just interrupt on the main thread where the object is instantiated?
There's no additional magic in Runnable. A Thread takes a Runnable and calls its run method on a new thread. End of story. Any other methods on that object are none of Thread's business. If you want to provide tighter integration between the calling thread and the created thread, that's on you to design.
What Silvio Mayolo says is correct, any thread can call any method of an object, passing a Runnable to a thread's constructor tells the thread to execute that Runnable's run method. If you want you can pass the same object implementing Runnable to several new threads and let them all run it. No magic here.
When you call Thread.currentThread(), that returns the thread that is executing the code. So as your posted code works now, if 1) a thread A starts a new thread B passing in this Runnable, and next 2) thread A calls shutdown on the Runnable, the result is that the interrupt flag is set on thread A, not on the thread B, the one executing the run method. Probably not what you want. It would be better to keep a reference to the new thread, and call interrupt on that.
Each thread gets a name generated for it. Try adding some lines like:
System.out.println("thread=" + Thread.currentThread().getName());
in your code and it will show you which thread is executing. You will see the new thread executing the run method, and the thread that created the new thread running the shutdown method.

Need some clarification on Java threads: start() and run()

According to the StackOverflow answers, start() creates a thread and executes the code in this new thread and run() executes the code in the current thread without creating any - as if it was a Runnable
But the docs, if I understood them properly, say that start() initializes a new thread an then, if you want to re-execute your code in the same thread, you call run()
Which one is right?
UPD
Okay, looks like calling run() manually is not a good practice and is at least useless. Are there some good ways to call the code in run()? Say, I have a relatively slow action that is required frequently, one instance at a time - what then?
As quoted, neither of them is right.
start doesn't create or initialize a thread. It starts a thread. From the documentation:
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The thread is created and initialized by calling the Thread constructor, which naturally you have to do prior to calling start. (That's the "external myth," anyway; I'd have to check the JVM spec, but I suspect it would probably be valid for a JVM to defer actual creation of the OS thread until/unless you called start.)
In the normal case, you never call the run method of a Thread instance directly. Instead, you start the thread via start and the JVM schedules a call to run on the actual thread assigned to that Thread instance. If you call run directly, it gets called on the thread you're using to do that, which probably isn't the one assigned to the Thread instance.
You may find the Java concurrency tutorial useful.
Re your comment below:
And how to re-execute the code in run()? Restart the thread or have some infinite loop with a boolean value controlling the execution?
The latter, but not an infinite loop, a loop with a termination condition. From the start documentation:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
So once run returns, that's it, you can't keep using the thread. Instead, you have the thread not return from run until its work is done. If you want to keep it around waiting for work, it should wait on a semaphore of some kind that you can signal from outside the thread, to wake it up to do some work.
A subsection of the tutorial above talks about one way to do that with Guarded Blocks using wait and notify/notifyAll.
Here's a simple example where every call to System.out.println prints the name of the thread on which the call was made so you can see which thread does what:
Live Copy
class Example
{
public static void main (String[] args) throws java.lang.Exception
{
Thread t= new Thread(new Runnable() {
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": Running run");
}
});
System.out.println(Thread.currentThread().getName() + ": Running main");
System.out.println(Thread.currentThread().getName() + ": Calling t.start()");
t.start();
System.out.println(Thread.currentThread().getName() + ": Calling t.join() to wait for thread exit");
try {
t.join();
} catch (InterruptedException ie) {
System.out.println(Thread.currentThread().getName() + ": Calling got InterruptedException");
}
System.out.println(Thread.currentThread().getName() + ": Program complete");
}
}
Example output:
main: Running main
main: Calling t.start()
main: Calling t.join() to wait for thread exit
Thread-0: Running run
main: Program complete
Note that our main thread just called start; then the JVM set things up so that run would be called on the thread we'd created.
Your confusion probably comes from the ambigous use of the terms thread, create and initialize. Without specifying what they exactly address its easy to misunderstand, because there are multiple concepts that the term thread is used to describe.
On one hand, there is the Thread object (that is created through new Thread(...) constructor). Thats not the thread in terms of actually executing anything. Its just a facade for the threading mechanism that implements a standardized API to interact with the OS/VM.
Just creating a Thread instance is basically not any different from creating any other java object. Nothing happens yet that has anything to do with actually adding a thread to the OS thread scheduler.
The thread on the OS side is actually created in a (private) native method start0(), the start() method performs some sanity checking, then calls start0() to actually create an OS-Level thread.
So the general order of actions is:
Create and Initialize a Thread-Object
Nothing out of the ordinary happens yet
You invoke start() on above Thread-Object
Delegates to native code to create an OS-Level thread. Entry point for the OS-Level thread is Thread.run() on the java side.
Executes Thread.run() on the new thread (default implementation of run delegates to the Runnable the Thread object was created with, or does nothing if no Runnable)
if I understood them properly, say that start() initializes a new thread an then, if you want to re-execute your code in the same thread, you call run()
This is incorrect. You need to understand that every Java program begins it's execution with the main thread. In other words, when you run a Java program that has a main method (e.g java MyProgram), a new execution stack is created with the main method at the bottom of this stack.
If a program creates a Thread instance in the main method and calls the start method on the thread instance, a new execution stack will be created with the run method at the bottom of the stack. You will now have two execution stacks. One with the main method at the bottom of the stack and the other with the run method at the bottom of the stack. These two stacks can complete their execution in parallel.
On the other hand, If you call run on a thread instance in the main method instead, it will simply be called in the same execution stack as the main method. A new execution stack will not be created. Therefore, calling run on a thread instance is as good as calling any other method on any other object and has no special meaning.
Here is the main difference between start() and run():
Thread#start: when program calls start() method the Java Virtual Machine calls the run method of this thread.
Thread#run: If you call run() method directly code inside run() will execute on current Thread.

What is the need of Thread start method? why not have only run method? [duplicate]

This question already has answers here:
What's the difference between Thread start() and Runnable run()
(14 answers)
Closed 8 years ago.
What is the need to run the thread through start method? Why not we call directly run method ?
What will happened if combined the code of start() and run()
to make it as single method run()
Dont explain the difference between both method, i want to know about this scenario.
When program calls start() method a new Thread is created and code inside run() method is executed in new Thread while if you call run() method directly no new Thread is created and code inside run() will execute on current Thread.
Each thread starts in a separate call stack.
Invoking the run() method from main thread, the run() method goes onto the current call stack rather than at the beginning of a new call stack.
Please refer What if we call run() method directly instead start() method? also read Difference between start and run method in Thread
You need to know that thread can have different states. Based on http://www.tutorialspoint.com/java/java_multithreading.htm there are 5 states of thread
new - thread was created and can be started
runnable - thread is executing
waiting - thread is waiting for other thread to finish; other thread will have to inform this thread that it finished by calling for example notify method on shared lock
timed waiting - similar to waiting but thread will stop waiting after some time automatically without waiting for signal from other thread
terminated - thread finished its task
run method contains only code which needs to be executed when thread will work (when it will be in runnable state).
start method is needed to take care of changing state of threat from new to runnable so it could start working and use its own resources (processor-time for instance) to execute code from run method.
When you call yourThread.run() code from run method will be executed by thread which invoked this method, but if you use yourThread.start() then code from run method will be executed using resources of yourThread.
Take a look at this example
public static void main(String[] args) {
System.out.println("main started");
Thread t = new Thread(){
public void run() {
try {Thread.sleep(2000);} catch (InterruptedException consumeForNow) {}
System.out.println("hello from run");
};
};
t.run();
System.out.println("main ended");
}
Code in run method will pause thread which runs it for two seconds (because of Thread.sleep(2000);) so you can see hello from run after two seconds.
Now output looks like this
main started
hello from run
main ended
because code in run method was executed by main thread (the one handling public static void main(String[] args) method), also because of two second pause part
hello from run
main ended
was printed later.
Now if you change t.run() to t.start() code in run method will be executed by t thread. You will see it by observing result which would be
main started
main ended
(from main stream) and after two seconds
hello from run
run() method defines what the thread will do. start() method starts the thread to perform its task implemented by the run method.
If you call the run method directly, it is performed by the caller thread. However, the start method causes to process the task in a newly started thread. In the former case, the caller thread waits for the run method to be completed. In the later case, on the other hand, the newly created thread executed asynchronously and so the caller thread continues its job without waiting the completion of the run method.
If you directly call the run() method of the thread then the code inside of that method will be run in the thread that calls the run() method. Calling start() will create a new thread and execute the code in the run() method on the new thread.
Put simply calling run() directly is probably a bug since you aren't actually creating a new thread.
See the following link for a reference.
http://javarevisited.blogspot.co.uk/2012/03/difference-between-start-and-run-method.html
In simple term
invoke Thread.start in order to start the new thread.
If you call run method directly then its just like a normal method call in the same thread.
What JavaDoc - Thread#start() states:
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
see Defining and Starting a Thread a Java Tutorial
Read more...

Running Thread by calling start() and run(), what is the difference?

It may be a basic question, i was confused with this,
in one file i have like this :
public class MyThread extends Thread {
#Override
public void run() {
//stuffs
}
}
now in another file i have this :
public class Test {
public static void main(String[] args) {
Thread obj = new MyThread();
//now cases where i got confused
//case 1
obj.start(); //it makes the run() method run
//case 2
obj.run(); //it is also making run() method run
}
}
so in above what is the difference between two cases, is it case 1 is creating a new thread and case 2 is not creating a thread ? that's my guess...hope for better answer SO guys.Thanks
start() runs the code in run() in a new thread. Calling run() directly does not execute run() in a new thread, but rather the thread run() was called from.
If you call run() directly, you're not threading. Calling run() directly will block until whatever code in run() completes. start() creates a new thread, and since the code in run is running in that new thread, start() returns immediately. (Well, technically not immediately, but rather after it's done creating the new thread and kicking it off.)
Also, you should be implementing runnable, not extending thread.
Calling start() will create a new execution thread, and then the run() will be executed in the newly created thread
where as directly calling run() will execute the code in the current thread
the simple answer to your question is this:
run(): runs the code in the run() method, blocking until it's complete
start(): returns immediately (without blocking) and another thread runs the code in the run() method
Calling start starts the thread. It does the underlying work to create and launch the new thread, and then calls run on that new thread.
Calling run just calls the run method, on the current thread. You never call run directly, use start.
run() method after calling start() : this is executed by your thread which is created by you, it is allocated processor to run independently.
run() method called by you : executed from your calling thread.
In one line directly calling run() is synchronous (your code will block until run() returns) and calling start() (your code will not wait for run to complete as it is called in other thread obj) is asynchronous.
When you directly use start() method, then the thread will run once using the Runnable instance you provided to it and then the thread will be unusable.
But to leverage the Thread Pooling and Scheduling capabilities that are inbuilt in Java, extending a Runnable or Callable is the way to go.
start() starts the thread. run() just runs the code, in the current thread.

Is it legal to call the start method twice on the same Thread?

The following code leads to java.lang.IllegalThreadStateException: Thread already started when I called start() method second time in program.
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
This happens the second time updateUI.start() is called. I've stepped through it multiple times and the thread is called and completly runs to completion before hitting updateUI.start().
Calling updateUI.run() avoids the error but causes the thread to run in the UI thread (the calling thread, as mentioned in other posts on SO), which is not what I want.
Can a Thread be started only once? If so than what do I do if I want to run the thread again? This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
From the Java API Specification for the Thread.start method:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
Furthermore:
Throws:
IllegalThreadStateException - if the thread was already started.
So yes, a Thread can only be started once.
If so than what do I do if I want to
run the thread again?
If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Exactly right. From the documentation:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
In terms of what you can do for repeated computation, it seems as if you could use SwingUtilities invokeLater method. You are already experimenting with calling run() directly, meaning you're already thinking about using a Runnable rather than a raw Thread. Try using the invokeLater method on just the Runnable task and see if that fits your mental pattern a little better.
Here is the example from the documentation:
Runnable doHelloWorld = new Runnable() {
public void run() {
// Put your UI update computations in here.
// BTW - remember to restrict Swing calls to the AWT Event thread.
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
If you replace that println call with your computation, it might just be exactly what you need.
EDIT: following up on the comment, I hadn't noticed the Android tag in the original post. The equivalent to invokeLater in the Android work is Handler.post(Runnable). From its javadoc:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* #param r The Runnable that will be executed.
*
* #return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
So, in the Android world, you can use the same example as above, replacing the Swingutilities.invokeLater with the appropriate post to a Handler.
No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException.
>
The reason is once run() method is executed by Thread, it goes into dead state.
Let’s take an example-
Thinking of starting thread again and calling start() method on it (which internally is going to call run() method) for us is some what like asking dead man to wake up and run. As, after completing his life person goes to dead state.
public class MyClass implements Runnable{
#Override
public void run() {
System.out.println("in run() method, method completed.");
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/*OUTPUT in run() method, method completed. Exception in thread
"main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
*/
check this
The just-arrived answer covers why you shouldn't do what you're doing. Here are some options for solving your actual problem.
This particular thread is doing some
calculation in the background, if I
don't do it in the thread than it's
done in the UI thread and the user has
an unreasonably long wait.
Dump your own thread and use AsyncTask.
Or create a fresh thread when you need it.
Or set up your thread to operate off of a work queue (e.g., LinkedBlockingQueue) rather than restarting the thread.
What you should do is create a Runnable and wrap it with a new Thread each time you want to run the Runnable.
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
It is as you said, a thread cannot be started more than once.
Straight from the horse's mouth: Java API Spec
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
If you need to re-run whatever is going on in your thread, you will have to create a new thread and run that.
To re-use a thread is illegal action in Java API.
However, you could wrap it into a runnable implement and re-run that instance again.
Yes we can't start already running thread.
It will throw IllegalThreadStateException at runtime - if the thread was already started.
What if you really need to Start thread:
Option 1 ) If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Can a Thread be started only once?
Yes. You can start it exactly once.
If so than what do I do if I want to run the thread again?This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
Don't run the Thread again. Instead create Runnable and post it on Handler of HandlerThread. You can submit multiple Runnable objects. If want to send data back to UI Thread, with-in your Runnable run() method, post a Message on Handler of UI Thread and process handleMessage
Refer to this post for example code:
Android: Toast in a thread
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
I have had to fix a resource leak that was caused by a programmer who created a Thread but instead of start()ing it, he called the run()-method directly. So avoid it, unless you really really know what side effects it causes.
I don't know if it is good practice but when I let run() be called inside the run() method it throws no error and actually does exactly what I wanted.
I know it is not starting a thread again, but maybe this comes in handy for you.
public void run() {
LifeCycleComponent lifeCycleComponent = new LifeCycleComponent();
try {
NetworkState firstState = lifeCycleComponent.getCurrentNetworkState();
Thread.sleep(5000);
if (firstState != lifeCycleComponent.getCurrentNetworkState()) {
System.out.println("{There was a NetworkState change!}");
run();
} else {
run();
}
} catch (SocketException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread checkingNetworkStates = new Thread(new LifeCycleComponent());
checkingNetworkStates.start();
}
Hope this helps, even if it is just a little.
Cheers

Categories

Resources