I am storing a bunch of threads objects in an arraylist. I want to be able to start these threads at random. Same thread can be started more than once. Before I start a thread object, I check on whether the thread is alive, and if they have either of NEW or TERMINATED status. This restriction because, I don't want to disturb the 'busy' threads. Now, for NEW threads, this works fine. But for TERMINATED thread, I get an exception.
When a thread ends, shouldn't it go back to being 'new'? Or are threads 'disposable' - like use once and done?
As it says in the documentation for Thread.start(), "It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution."
It is better for you to keep hold of Runnable instances and implement your own logic for keeping track of when the execution of each one of them finishes. Using an Executor is probably the simplest way to run the Runnables.
You should probably be using the awesome stuff provided in java.util.concurrent
. Based on your description, ThreadPoolExecutor
sounds like a good thing to check out.
This is the way I did it
class GarbageDisposalThread extends Thread {
public void start() {
try {
super.start();
} catch( IllegalThreadStateException e ) {
this.arrayList.remove(this);
this.arrayList.add( new GarbageDisposalThread( this.arrayList ));
}
}
private GarbageDisposalThread() {
}
public GarbageDisposalThread( ArrayList<Whatever> arrayList ) {
this.arrayList = arrayList;
this.start();
}
public void run() {
// whatever the code
}
private ArrayList<Whatever> arrayList = null;
}
that's it! you can change the code according to your needs :P
Java threads cannot be restarted.
From the javadoc:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
See the Thread.start() javadoc for more information.
There are other ways to accomplish what you are trying to do. For example, you could use new Threads that continue the work that was done in the Thread that has finished execution. You may also want to investigate the java.util.concurrent package.
From another post...
You could use ThreadPoolExecutor, which would allow you to pass in tasks and let the service assign a thread to a task. When the task is finished, the thread goes idle until it gets the next task.
So, you don't restart a thread, but you would redo/resume a task.
来源:https://stackoverflow.com/questions/5411509/terminated-thread-revival