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.
Related
i have found that isAlive() method is not working when executing a thread using ExecuterService.
And interrupt() and stop() method is also not working.
The code i used:
Thread t1=new Thread(()->{
try{
Thread.sleep(10000);
} catch(InterruptedExeception ie){
System.out.println("Interrupted");
}
Thread.sleep(5000);
System.out.println("It's Done");
});
ExecuterService excuter=Executers.newSingleThreadExecuter();
excuter.execute(t1);
Thread.sleep(2000);
System.out.println(t1.isAlive());
Thread.sleep(2000);
t1.interrupt();
t1.stop();
My expected output is :
true
Interrupted
Actual output is :
false
It's Done
I need reason for this behavior. And I want to know what is the solution for the problem and how I use these methods when a Thread is running inside a ThreadPool.
The stop() method does not work. You can't stop threads like this. A thread needs to opt into allowing itself to be stopped; you'd for example update a (volatile, or AtomicBoolean-style) boolean, and the thread runs a loop, and on each loop, checks that boolean; if it's false, it ends. There is no way to stop arbitrary threads in their tracks. At all. You can google for information about why Thread.stop is deprecated (and effectively doesn't work at all anymore, even though the method is still around, primarily as vehicle for the documentation on why you can't do that anymore).
Threads implement runnable, which is why you're even allowed to pass that thread to the executor method, but the entire thread infra isn't being used at all. You should update this code to be Runnable r = () -> { ... } and pass that. Your code as written is misleading you into thinking that's the thread that is being run. It's not, which is why you're getting false for .isAlive().
Executors as a rule don't expose the way they do the job, they just do it. If you want to check if the job is running, set a (volatile, or AtomicBoolean) boolean to true upon entry, and to false upon exit. Alternatively, don't bother with an executor service, just start your thread, if you really want to use thread functionalities such as .isAlive().
t1 is not a thread.
t1 is a Thread instance, but a Thread instance is not the same thing as a thread, and the way you are using t1, no thread is ever created. Think of a Thread instance as a handle that you use to create and control a thread. The thread would be created if your program called t1.start(), and then the t1.isAlive() and t1.interrupt() and t1.stop() calls all would operate on that new thread.
Besides being a Thread instance, t1 also happens to be a Runnable instance, which is what the executer.execute(...) call wants. Being a Runnable just means that t1 has a run() method. There are various ways that run() method could be called:
You could start the thread, t1.start(), in which case, the new thread would call it,
You could (you did) give it to an Executor. When you do that, the Executor arranges to have one of its worker threads call your run() method.
You could simply call it -- t1.run() -- which is no different from calling any other method that your code defines.
You could pass it to any other library method that wants a Runnable. (I don't know how many there are, maybe a lot.)
If you want t1.run() to be called in a thread that your code can control, then call t1.start() to create that thread. If you want it to be called by an executor service, whose threads you should not attempt to control, then do what you did: call excuter.execute(t1);
Just don't do both. That probably isn't what you want.
P.S., If you want to continue using the Executor service, then you probably should change your declaration of t1. Since it only needs to be a Runnable in that case, you can write:
Thread t1=new Runnable(()->{
...
});
That way, people reading your code won't scratch their heads and wonder whether you knew what you were doing.
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...
I've been using threads for 2-3 days now, and I've got a quick question regarding methods. I'm making an Android application and it starts off with the main UI thread (let's call it the "UI Thread" for clarity). I'm spawning a new thread using the following code:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
someMethod();
}
});
thread.start();
My question is, will someMethod() also run on the new thread that I just created because I'm calling it from there? Or will it run on the UI thread? For reference, someMethod() is located outside outside of the method that's creating the new thread.
If someMethod() won't run on the new thread, how do I make it do so? Thanks.
will someMethod() also run on the new thread that I just created because I'm calling it from there?
Yes, that is exactly what happens. The method is just code. It's independent of the thread-of-control that happens to be running in it at a given point and time. This also means that there could be multiple threads executing that code at any given point in time if there are multiple cpu/cores.
You should take a look at Callable<V> and Future<T>, there you can call methods, that are not processed on the calling thread. You shouldn't work with threads anyway nowadays.
There are more modern approaches available.
Here is a link that should give you an idea http://www.vogella.com/articles/JavaConcurrency/article.html#futures
All of the actions taken by run, including calling someMethod, stay on the new Thread unless that code tells Java to run something in another thread (like with invokeLater or by using an Executor).
Or is it?
I have a thread object from:
Thread myThread = new Thread(pObject);
Where pObject is an object of a class implementing the Runnable interface and then I have the start method called on the thread object like so:
myThread.start();
Now, my understanding is that when start() is called, the JVM implicitly (and immediately) calls the run() method which may be overridden (as it is in my case)
However, in my case, it appears that the start() method is not called immediately (as desired) but until the other statements/methods are completed from the calling block i.e. if I had a method after the start() call like so:
myThread.start();
doSomethingElse();
doSomthingElse() gets executed before the run() method is run at all.
Perhaps I am wrong with the initial premise that run() is always called right after the start() is called. Please help! The desired again is making executing run() right after start(). Thanks.
Um... the run() method will run in a different thread. That, per definition, means you cannot make any assumptions about before or after which statements in the current thread it will execute, unless you synchronize them explicitly.
Now, my understanding is that when start() is called, the JVM implicitly (and immediately) calls the run() method ...
That is incorrect. It does implicitly call run(), but the call does not necessarily happen immediately.
The reality is that the new thread becomes available to be scheduled at some point in time after the start() call is made. The actual scheduling is up to the native scheduler. It could happen immediately, or the parent thread could continue for a period before the child thread is scheduled.
To force your thread to start running immediately (or to be more accurate, to start running before doSomethingElse()), you need to do some explicit synchronization; e.g. something like this:
java.util.concurrent.CountDownLatch latch = new CountdownLatch(1);
new Thread(new MyRunnable(latch)).start();
latch.await(); // waits until released by the child thread.
doSomethingElse();
where
class MyRunnable implements Runnable {
private CountDownLatch latch;
MyRunnable (CountDownLatch latch) { this.latch = latch; }
public void run() {
doSomeStuff();
latch.countDown(); // releases the parent thread
doSomeMoreStuff();
}
...
}
There are other ways to implement the synchronization using the concurrency classes, or Java's mutex / wait / notify primitives1. But explicit synchronization between the two threads is the only way to guarantee the behavior that you require.
Note that the doSomething() call in the child thread will complete before the parent thread is released, but we can say nothing about the order of execution of doSomethingElese() and doSomeMoreStuff(). (One might run before the other and vice versa, or they might run in parallel.)
1 - Using wait / notify is not recommended, but it may be your only option if the concurrency APIs are not available; e.g. on Java ME.
run() is the first thing within your code that the new thread does, but there's some set-up work that the new thread does first, and there's no guarantee that any significant amount of work will by done by the new thread before the original thread goes on to call doSomethingElse().
You're right in thinking that there are no guarantees here. Making assumptions about the behaviour of multithreaded code is the source of much pain - try not to do it!
When you call myThread.start(), your thread becomes available for execution. Whether it will actually gain CPU, and for how long -- it's up the the OS scheduler. In fact, your run() may be getting control immediately, but losing it before it can do anything you can notice. The only way to ensure that your thread executes what you need before doSomethingElse() is to use explicit synchronization.
You've started a new thread. That thread runs in parallel to the thread that started it so the order could be:
pObject.run();
doSomethingElse();
or
doSomethingElse();
pObject.run();
or, more likely, there will be some crossover. pObject.run() may run in the middle of doSomethingElse() or vice versa or one will start before the other finishes and so on. It's important to understand this and understand what is meant by an atomic operation or you will find yourself with some really hard-to-find bugs.
It's even more complicated if two or more threads access the same variables. The value in one may never be updated in one thread under certain circumstances.
I highly suggest:
You don't make your program multi-threaded unless you absolutely need to; and
If you do, buy and read from cover to cover Brian Goetz's Java Concurrency in Practice.
calling the start method on a Thread Object may not make the jvm invoke the run() method immidiately, rather it makes the thread a runnable and ready for execution, in this case the parent thread first executes its code and then passes control to the child thread, if u want the child thread to execute before the parent thread code is executed use the chileThreadObject.join() method in the parent 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