14
How do I stop a running thread with Java commands?
14
How do I stop a running thread with Java commands?
15
There is the method Thread.stop()
which has this purpose. However it is obsolete (deprecated). It still works if used, but there are strong reasons for not using it.
When a thread is suddenly interrupted, it can leave important operations unfinished. For example, imagine that it was saving information in a file and while being interrupted suddenly the file ends up corrupted. Or suppose she was doing some critical operation with some object in memory and suddenly being interrupted, this object ends up in an inconsistent and corrupted state? This is the reason why the Thread.stop()
was discontinued.
The Thread.stop()
works by suddenly launching a ThreadDeath
inside the thread that was stopped by force. This means that the thread will still have the blocks finally
executed, and if she gives a catch (ThreadDeath e)
or a catch (Throwable e)
, she will be able to capture the ThreadDeath
and end up not being stopped. This may sound good, but if the ThreadDeath
is launched from within a block finally
, the finally
ends up being interrupted leaving something very important unfinished. If you try to treat this by capturing the ThreadDeath
, another Thread.stop()
can cause a new ThreadDeath
within the code that should be dealing with the ThreadDeath
, and because of this, in practice it is impossible to treat the ThreadDeath
appropriately.
To make matters worse, let’s assume that the thread was inside a code belonging to some library that was doing some operation with arrays, anyway, something that has nothing to do with the Thread.stop()
or with the ThreadDeath
. You even have a catch (ThreadDeath e)
somewhere outside the library in a method you use it. When the ThreadDeath
is captured, the library code only ran in half leaving a lot of things inconsistent. So, how do you fix these things? How do you even figure out what’s been inconsistent?
Beyond the Thread.stop()
there is a variant Thread.stop(Throwable)
(also obsolete) that for the thread with an arbitrary exception, rather than a ThreadDeath
. This is even worse because you continue with the same problem of Thread.stop()
, but now instead of a ThreadDeath
you have any exception and therefore it gets harder to write code that can handle it. In more modern versions of JDK, this method only launches a UnsupportedOperationException
, this being one of the very few cases where there has been a break of purposeful backcompatibility in Java.
There is the method Thread.suspend()
which stops the thread and lets it continue later with Thread.resume()
. However, this method can also end up leaving important operations incomplete and inconsistent objects due to sudden thread interruption. Moreover, it can result in deadlocks, since any Locks on objects (those that are obtained in blocks and methods synchronized
) remain locked to the suspended thread. For this reason, these methods are also obsolete.
There is also the method Thread.destroy()
(obsolete) that should stop the thread immediately and destroy it. This method has never been implemented and trying to use it results in an exception. Had it been implemented, the result would have been similar to a Thread.suspend()
where there is no option to make a Thread.resume()
.
To stop a thread gracefully, it must be running code that provides for its interruption gracefully. This can be simply encoding the thread to check once in a while whether a variable boolean
or AtomicBoolean
or some special condition in order to determine whether the thread should stop or not. That is, the thread code is designed to know when it should be stopped and voluntarily do so gracefully.
The recommended way to interrupt threads is with the method Thread.interrupt()
. This method does not actually interrupt the thread, it just sets a flag on it (the interrupt status). You can know if the current thread was interrupted by using the methods Thread.interrupted()
and Thread.isInterrupted()
. These methods return a boolean
whether the thread was interrupted or not. The difference between them is that the Thread.interrupted()
clears the interrupt status (sets it to false
), while the Thread.isInterrupted()
does not change it. In addition, the Thread.interrupted()
is a static method that checks and clears the interrupt state of the thread that invoked it (Thread.currentThread()
), while the Thread.isInterrupted()
is a class instance method Thread
.
Various JDK methods (eg: Thread.sleep
and Object.wait
) make the exception InterruptedException
. This exception is thrown when the thread that is running these methods (Thread.sleep
, Object.wait
or others) is interrupted by the use of Thread.interrupt()
. This way, it is possible to interrupt a thread that is trapped in a Thread.sleep
or Object.wait
. It is important that the interrupted thread handles the InterruptedException
satisfactorily (simply capturing it and ignoring it without thinking properly about what is being done, is not a good practice of programming). When the InterruptedException
is launched, thread interrupt status is cleared (set to false
), once when the exception is being captured, the interruption is already being dealt with.
If you are designing a method that may be stuck for a long time, a good alternative is to check the Thread.isInterrupted()
or the Thread.interrupted()
and launch the InterruptedException
. For example:
public void metodoDemorado() throws InterruptedException {
while (/*alguma coisa*/) {
// faz qualquer coisa
if (Thread.interrupted()) throw new InterruptedException();
}
}
Browser other questions tagged java
You are not signed in. Login or sign up in order to post.
I’m still going to open a discussion on the goal to find a better translation for deprecated. "Depreciated" means something else :)
– bfavaretto
@bfavaretto I’ve always called "obsolete"...
– mgibsonbr
@mgibsonbr I too, but as a verb does not work (it must say "make obsolete"). And perhaps there is a term that better conveys the meaning. In Portuguese there is even "deprecate", but it is legal jargon used in a slightly different way (although there are semantic similarities with the English term).
– bfavaretto
@bfavaretto "Discontinued" then? Type "X method support has been discontinued". This "Portuguese Language" is missing... P
– mgibsonbr
@bfavaretto opens there in PL ;)
– Jorge B.
@Guilhermenascimento I thank the edition. I only ask you to take a little more care with the gender (obsoleteto vs obsoletethe).
– Victor Stafusa
It sounded better to me at first, but I could be wrong.
– Guilherme Nascimento
@Guilhermenascimento The method is obsoletethe, and not obsoleteto. Because method is a masculine noun. :)
– Victor Stafusa