This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 9 years ago.
What are all the different possibilities to bring the dead thread back to runnable state.
If you look at the Thread Life Cycle Image, there is no way you can go back to new position once your thread has terminated.
So there is no way to bring back the dead thread to runnable state,instead you should create a new Thread instance.
From the JavaDocs...
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.
You'll have to start a brand new instance.
Preferably, the actions you want to execute should be wrapped up in a Runnable interface, that way you can simply pass the Runnable to a new instance of Thread
I guess you extended the Thread class and you have overridden the run method. If you do this you are tying the runnable code to the Thread's lifecycle. Since a Thread can not be restarted you have to create a new Thread everytime. A better practice is to separate the code to run in a thread from a Thread's lifecycle by using the Runnable interface.
Just extract the run method in a class that implements Runnable. Then you can easily restart it.
For example:
public class SomeRunnable implements Runnable {
public void run(){
... your code here
}
}
SomeRunnable someRunnable = new SomeRunnable();
Thread thread = new Thread(someRunnable);
thread.start();
thread.join(); // wait for run to end
// restart the runnable
thread = new Thread(someRunnable);
thread.start();
This practice makes it also easy if you need to remember the previous run state.
public class SomeRunnable implements Runnable {
private int runs = 0;
public void run(){
runs++;
System.out.println("Run " + runs + " started");
}
}
PS: Use a java.util.concurrent.Executor to execute Runnables. This will decouple thread management from execution.
Executor executor = Executors.newSingleThreadExecutor();
...
SomeRunnable someRunnable = new SomeRunnable();
executor.execute(someRunnable);
Take a look at Executor Interfaces
The thread is a separate light weight process which executes independently irrespective of other threads. Once its execution is complete, there exists no means to restart it.
The other obvious solution is: if you need the thread functionality many times, don't let the thread die. Instead of letting it exit, and so terminate itself, shove in a while(true) loop with a suitable wait at the top. You can then make it 'restart' its work by signaling it.
This is much quicker, safer and more efficient than continually creating/terminating/destroying threads.
When the execution of run() method is over, as the job it is meant is done, it is brought to dead state. It is done implicitly by JVM. In dead state, the thread object is garbage collected. It is the end of the life cycle of thread. Once a thread is removed, it cannot be restarted again (as the thread object does not exist).
Read more From Here about life cycle of Threads.
Thread has many different state through out its life.
1 Newborn State
2 Runnable State
3 Running State
4 Blocked State
5 Dead State
Thread should be in any one state of above and it can be move from one state to another by different methods and ways.
When a thread is completed executing its run() method the life cycle of that particular thread is end.
We can kill thread by invoking stop() method for that particular thread and send it to be in Dead State.
Related
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
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
I want to run a thread when I press a button
public void ButtonClick(){
Thread thread = new Thread(){
public void run(){
Log.i("Test", "I'm in thread");
}
};
thread.start();
}
My question is : I want to click several times on this button. Are several thread still existing after the message "I'm in thread" is printed? Or each time the run function is finished, the thread is destroyed?
In case I create several threads which are running at the same time, how can I close them in a clean way?
Thanks for your help!
Are several thread still existing after the message "I'm in thread" is
printed?
No. Each of them will be destroyed automatically.
In case I create several threads which are running at the same time,
how can I close them in a clean way?
No need to stop threads, they will be destroyed automatically once they finish their task(execution of run).
To handle the concurrency and safety you should look in to java.util.concurrent which is utility framework for handling concurrency in java.
Are several thread still existing after the message "I'm in thread" is printed? Or each time the run function is finished, the thread is destroyed?
In your case, you are creating many threads since a Thread is created for every button click.
The life span of Thread is over after completion of last statement in run() method. After execution of run() method, the thread will enter into TERMINATED State and it can't be re-run.
Better solution is not creating a new Thread for every button click. If you need more Threads in your application, go for a pool of Threads.
Java provides Executor framework for this purpose. It manages Thread life cycle in better way.
Use one of APIs, which will return ExecutorService from Executors
e.g. newFixedThreadPool(4)
Have a look at this post and this article for more options.
In case I create several threads which are running at the same time, how can I close them in a clean way?
You can shutdown the ExecutorService as quoted in below SE post:
How to properly shutdown java ExecutorService
Since you are using Android, you have one more good alternative for multithreading : HandlerThread and Handler
Refer to below post for more details:
Android: Toast in a thread
Creating Thread everytime is a bad idea use Thread Pool.
create a class implementing Runnable instead of Anonymous thread ... pass runnable object creating as many threads as you likeSince creating Anonymous Runnable object creates only one object thus limiting you to achieve your requirements. Check the thread status before creating another or create a thread group (depreciated) or a thread pool using concurrency you use callable instead of runnable and pass it to thread pool of definite size or you could convert runnable to callable and then pass it to the pool as many times as you like
class Thop implements Runnable
{
public void run()
{
// operation
}
}
The question is, is it possible to have an external thread or do they have to be internal to the class they run in. If so could someone show me how. (external thread)
A thread, or, more precisely, a thread of execution is something, and the class Thread is something closely related but different, and it seems that you are mixing up these two concepts.
You can think of a thread of execution as a machine that will execute operations sequentially. One way to define and run such a machine is to write a class MyClass with a main() method and call java MyClass.
Another way is to create a new instance of the Thread class and call its method start(). This will create a new thread of execution which will run the code that is in the run() method of the Thread class, which does nothing by default. For this to be useful, you usually override the run method, which is what I think you are calling a thread internal to the class...:
class MyThread extends Thread {
#Override public void run() {
// ... some code ...
}
}
// ...
final Thread t = new MyThread();
t.start();
In this example, after the run() method of the class MyThread returns, the thread of execution associated to that instance of MyThread will terminate (just like when your single-threaded program returns from -- or reaches the end of -- your main() method).
Another possibility is to pass the Thread an instance of a Runnable. Then you separate the 2 concepts: the thread of execution, which is represented by an instance of Thread, will execute the code in the instance of Runnable:
class MyRunnable implements Runnable {
#Override public void run {
// this code will get executed by a thread
}
}
// ...
final MyRunnable r = new MyRunnable();
final Thread t = new Thread(t);
t.start();
This maybe closer to what you call an external thread, although this nomenclature is highly unconventional.
So, you see that there are 2 different, but closely related, concepts here.
Now, in Java you have a way to create a thread of execution that will be waiting for you to give it some code to execute. After it is created, it goes to a pool, and sits there. You submit some code for it to run, and when it finishes, instead of terminating, the thread of execution keeps alive and goes back to that pool. Maybe this is what you are looking for.
To do it, you usually use an ExecutorService. For example:
class MyMainClass {
private static final ExecutorService es = Executors.newFixedThreadPool(10);
public static void main(String... args) {
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
}
}
In this example, the pool contains 10 threads of execution. You can submit any amount of instances of Runnable for it, and it will distribute them among the 10 threads. Each call to submit(...) on the ExecutorService returns an instance of Future, which you can use to know if the thread of execution that was running your Runnable did already finish, and if it finished successfully or due to an uncaught exception.
I suggest that you take a look at the javadocs for all the classes I mentioned here: Thread, Runnable, ExecutorService, Executors and Future. There's a lot to learn from that documentation!
As a final note, remember that if you start playing with threads and ExecutorServices, you will get all kinds of headache. You will have to think about situations in which the execution cannot proceed (deadlocks, livelocks), about operations that need to be atomic (ie, incrementing a variable from different threads), memory visibility (ie, if you change the value of a field without "taking care", it can happen that other threads will never notice the change to that field!). Also remember that the JVM won't die until every last non-daemon thread finishes; in other words, the example above will never terminate, even if all the submitted Runnables finish, because the threads of execution in the ExecutorService are still alive!
I have a Thread which runs my game loop. I want to be able to run this game loop each time I start a new game. But since the threads in Java can only be started once, how can I do this?
Create a new Thread around the same Runnable instance and start that.
Since you want the Thread that runs the game loop to keep running it, you need to code it something like this:
public class GameLoop implements Runnable {
...
public void run() {
while (gameNotFinished) {
// do stuff
}
}
}
If that is not working, then the chances are that the run() method is dying because of an exception that you are not catching / logging, and therefore not noticing.
1. When you say that "you need to run a thread", i means you want to start a sub-task on a separate thread.
2. Now if you mean this certain sub-task, then please prefer to run a new thread.
3. As you said But since the threads in Java can only be started once
This means that when a thread (thread of execution) completes its run() method, then the Thread object associated with it permanently looses its threadness, right....
But if this thread is from a pool, then the pool itself manages the Thread objects and its reused. Try using Executors from java.util.concurrent package.
1) The short answer is precisely what SLaks already said: just "...create a new thread around the same runnable instance and start that."
2) I think you might be confused about the distinction between the everyday meaning of "start", and the semantics of the Java Thread method "start()". This tutorial might help:
http://www.geom.uiuc.edu/~daeron/docs/javaguide/java/threads/states.html
3) Should you wish to re-use the same thread, you can use the methods "wait()" and "resume()":
http://www.javabeginner.com/learn-java/java-threads-tutorial