I'm wondering how to stop an unresponsive thread in Java, such that it's really dead.
First of all, I'm well aware of Thread.stop()
being deprecated and why it should not be used; there are already many excellent answers on this topic, cf. [1][2]. So, the question more precisely is, whether it's actually technically possibly to kill a thread which code is not controlled by us but possibly hostile and not responding to interrupts.
In the simplest case, a hostile thread would be running while(true);
, but it could as well be using up memory or other system resources to do more damage. Calling interrupt()
on that thread is obviously ineffective. What about calling stop()
instead?
I have run this in a debugger and, in fact, the thread really disappears. But is this approach reliable? The hostile thread could be prepared for this case; think of try{run();}catch(ThreadDeath t){run();}
where it catches the ThreadDeath
that is produced when we call stop()
and recursively calls itself again.
As an outside observer, we cannot see what is going on; Thread.stop()
always runs silently. Worst of all, the usual diagnostics won't work anymore (tried this while debugging on Corretto 1.8.0_275 Windows x64): Thread.getState()
always returns RUNNABLE
regardless of success in killing the thread, same goes for Thread.isAlive()
(always true).
It may not be possible, at least not reliably in every scenario.
IF I understand the mechanism correctly (and there is some uncertainty there), if the code executes in such a way that there are no safepoints during the execution (for example in counted loops), it is not possible for the JVM to signal to the thread that it should stop (the thread never polls for an interrupt).
In such a scenario, you need to kill the JVM process, rather than the thread.
Some extra reading:
How to get Java stacks when JVM can't reach a safepoint
Counted loops
In a nutshell, there's no 100% reliable way to stop a Thread
the way you'd like it.
This is an explanation for others who don't know why, anyone who knows the issue can skip this.
The way how threads are intended to be terminated forcefully is with the interruption state of the Thread
. A Thread
should be terminated with its interrupt()
method is called which sets a boolean flag to true
.
When the interruption flag is set to true
, the Thread
should terminate itself with virtually no delay.
Anyway the Thread
can choose to simply ignore this and keep on running.
This is when the stop()
method can be called that forces the Thread
to terminate. The problem is that this method messes up concurrency, can damage objects and the program can be corrupted without a warning for the user. See Why the stop()
method is deprecated?
At the end I could think of two possible ways, one is basically your way, the other one is safer but more complicated.
As an example, a hostile third party .jar
which contains a Thread
that refuses to terminate can cause these problems.
This solution isn't completely safe but based on the usage this may be acceptable unless you really like security.
Try to first to call the interrupt()
method on the Thread
and give it a bit time to terminate.
If the Thread
doesn't respond, you can either:
Thread
again.stop()
the thread and hope for the best.The safest solution I can think of is creating a whole new process to run the Thread
in. If the Thread
doesn't want to terminate after interrupt()
, you can just end the process with System.exit(-1)
and let the OS handle it.
You need Inter Process Communication to communicate with the other process and that makes it a lot more complicated but also safer.
How do you kill a Thread in Java?
What is an InterruptedException in Java? (Disclaimer: I've answered it)
What does java.lang.Thread.interrupt() do?
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