What happens to Java thread after a join call with timeout
What state is a Java thread in after you call join with a timeout value, and the timeout passes. So for instance you have the following code:
Thread thread = new Thread();
thread.start();
thread.join(TIMEOUT);
and the timeout passes and the thread hasn't returned what is the state? What do I need to be aware of to make sure I don't leak threads. My initial assumption is that after the join call doing something like:
if (thread.isAlive())
{
thread.interrupt();
thread = null;
}
To check if the thread is still running and if so 开发者_JAVA百科interrupt it, and then null it out to make sure it gets garbage collected.
The Javadoc states that the join(time) function will wait at most that many milliseconds for the thread to die. In effect if the timeout passes your code will stop blocking and continue on. If you are worried about 'leaking threads' in this case you probably should redesign so that you don't have to join the thread and can observe the state of the running thread. Furthermore calling an interrupt on the thread is bad mojo.
class MyThread extends Thread {
private boolean keepRunning = true;
private String currentStatus = "Not Running";
public void run() {
currentStatus = "Executing"
while(keepRunning)
{
try {
someTask()
currentStatus = "Done";
} catch (Exception e) {
currentStatus = "task failed";
keepRunning = false;
}
}
}
public stopThread() {
keepRunning = false;
}
}
Above might be a better example to work off of to work with threads. You need not set the thread to null explicitly, but for example if you're storing threads in an ArrayList remove it from the list and let Java handle it.
There is a little danger using the join with a timeout. Under certain circumstances the calling thread will stuck in the join method forever, even if we pass a timeout...
See http://insidecoffe.blogspot.com/2011/12/when-timeout-fails-in-threadjoin.html
and the timeout passes and the thread hasn't returned what is the state?
The state of the thread at that point is indeterminate. The best you can say is that it won't be NEW, and probably won't be TERMINATED. (But even in the latter case, it could have gone into TERMINATED state between the timeout having fired and the calling code having caught the timeout exception.)
About this code:
if (thread.isAlive()) {
thread.interrupt();
thread = null;
}
That is guaranteed to deliver the interrupt if the thread is still alive. (There is a small chance that you will attempt to interrupt a thread in TERMINATED state, but my reading of the javadoc for interrupt()
is that that is harmless.)
What happens with the interrupt is entirely up to the thread. Specifically, there is no guarantee that the thread will either see the interrupt, or do the expected thing; i.e. finish. (A well-behaved thread should check the interrupted flag regularly, and should not squash the "interrupted" exceptions on wait(...)
, sleep(...)
, etc.)
The assignment of null
to thread
will have minimal effect. If the thread is still running, it / its resources won't be garbage collected anyway. If the thread is terminated, this may render the Thread
object eligible for garbage collection. But that won't make much difference. When a thread goes into TERMINATED state, its stack is automatically freed, it is removed from its thread group, and its link to its Runnable
is nulled. Once that has all been done, the Thread object occupies a minimal amount of memory: nothing to be concerned about from the perspective of storage leakage.
Assuming you are checking for interruptions (Thread.interrupted(), and InterruptedException) I cannot see a reason why this should not work.
After the join finish successfully I guess the thread could be in any Thread.State but NEW
join
will cause the calling thread to wait for the thread join
was invoked on, to die, i.e. finish it's execution. So the state of thread
in your example at the moment the timeout has expired will be anything that is not TERMINATED
(which is why the timeout occurred as opposed to join
returning 'naturally' (in which case thread
would be in the TERMINATED
state) - of course, thread
could almost immediately transition into the TERMINATED
state, just after the timeout happened).
The state of the calling thread will become RUNNABLE immediately after the time expires and until that time, it would have in the TIMED_WAITING
state.
精彩评论