I know that "Once a thread has been started, it can never be started again".
But I want to know why?
What's the wrong if it is allowed to start again later in another time?
Why, the only time you can start a thread is when it is in the NEW state? Why it can't be also after DEAD at least?
public class ThreadDemo {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
thread.start(); // java.lang.IllegalThreadStateException
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("run().Thread.currentThread().getName() : " + Thread.currentThread().getName());
}
}
Note : I have gone through these posts. But my question is much more specific and descriptive.
Here, please note that I want to know this mainly to understand the threads internal functionalities and how the related aspects like GC works with thread states.
Because the Thread
implementation does not allow it. You could always create another Thread
instance with your Runnable
like
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
Edit
JLS-17.4.3. Programs and Program Order says (in part),
A set of actions is sequentially consistent if all actions occur in a total order (the execution order) that is consistent with program order, and furthermore, each read r of a variable v sees the value written by the write w to v such that:
w comes before r in the execution order, and there is no other write w' such that w comes before w' and w' comes before r in the execution order.
Sequential consistency is a very strong guarantee that is made about visibility and ordering in an execution of a program. Within a sequentially consistent execution, there is a total order over all individual actions (such as reads and writes) which is consistent with the order of the program, and each individual action is atomic and is immediately visible to every thread.
If Thread
instances could start again then the implementation of sequential consistency may well be impossible.
I can give you some points.
Garbage Collection: Active threads are considered as roots for Garbage Collection.
Means to say if some object is reachable from an active thread then it cannot be garbage collected.
Now if a thread is inactive (dead) any gc algorithm will determine that if a particular object which was only reachable by that thread is now eligible for Garbage Collection then it will collect
that object. But now if you again make your thread active its a problem because it will have a corrupted view of its stack because many objects might have been garbage collected.
Your whole program will go haywire.
To workaround this problem you will have maintain one more state lets call it GC_COLLECTABLE. It means thread is active means that its status != GC_COLLECTABLE. Now then the question arises how ad when the programmer will set this status. Its kind of same problem where cannot stop a thread or determining when certain objects must garbage collected. Its in itself a very complex problem to solve. The easiest way to workaround this problem is to not have a thread active once its dead or cannot restart it.
thread.join(): As Eliott suggested . Suppose there are three threads T1 T2 and a restartable thread RST. Now suppose T1 and T2 both call RST.join(). Problem when T1 and T2 will get out of join. If threads can be started again then join method is infinite. If you allow join to return after a DEAD state then there is race and undetermined behavior causing T1 to finish join() but T2 still lingering because RST has been already re started.
API change: How do you suggest this should be implemented.
Thread.start(); // Would this method suffice. Probably not
What will happen if i called Thread.start() in a loop -> will it will create new threads if previous threads are not dead or will restart the dead threads (Sounds like Executors.newCachedThreadPools)
-> or throw Exceptions if a the current thread is not dead or restart the thread Not a very good way this will make your program more non-deterministic. Because the same thread can take variable amount of time for the same task therefore you will have problem predicting your program output. And at the least you need a signature change for a checked exception from a start method or define a new method restart but it will have the same problem as above.
From my perspective the first point is alone enough to move from restarting the thread. Also you can have the similar functionality by using ThreadPools where a thread can be reused for different/similar tasks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With