I was wondering if there is some way in Java to stop thread immediately. I don't want to check its interrupted status, I need to stop it immediately. That's because in thread's run method there are many calculations and to achieve what I want using interrupted I would have to inject status check everywhere. So is there some way to interrupt thread immediately? Maybe stop() method? I know it's is said it shouldn't be used because of deadlocks but if it could solve my problem (even if it would cause another ;) ) I could use it. So? P.S. I know there were other, similar questions but everywhere people give similar questions to interrupted() which doesn't suit me.
The question/answer that #Alya'aGamal points to is the right one.
If your app's design assumes that forcibly stopping a thread, or a process, or a program (like using kill -9 or stopping it via the Task Manager on Windows) is an okay thing to do, then you really need to justify that, because it sounds like a bad design choice. If you used someone else's app and the only way to close it on demand was to forcibly stop it, wouldn't you think that was a rather major flaw?
If you have long-running loops or algorithms and it's important to be able to stop them at an arbitrary point then you MUST put some kind of regular status or signal check in place in order to do this properly.
Always design your apps in a way such that there is a nice, friendly, graceful way for them to exit from all situations other than things outside your control (e.g. another app starts saturating the CPU, a hard disk dies, a RAM chip gets fried, a meteor hits the Earth, etc.)
As others have said, it's not a good idea to just kill a thread, which is why the stop() method has been deprecated. It's just too easy to introduce deadlocks this way. There are other reasons why stopping a thread externally is bad, but I won't get into them here.
Status checks really are the only other way to go, but I can understand why you'd want to avoid them. Checks add overhead and make the code cumbersome if your run() method has many lines of code... but there's simply no other thread-safe way to stop a thread.
That said - there are four components of deadlock: mutual exclusion, hold and wait, non-pre-emption, and circular wait. If you can guarantee that any one of these conditions will never be met inside your run() method, then you will never encounter a deadlock by calling stop().
Related
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.
Why?
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.
Quick & Dirty
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:
terminate the program and warn the user to not run that Thread again.
stop() the thread and hope for the best.
Complicated & Safe
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.
Related
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?
For me isAlive returns false if the process finishes due to Thread.stop.
I've made the following example, and it successfully kills the errant thread.
import java.util.Arrays;
public class BrokenThreads{
static boolean[] v = { true };
public static void call(){
try{
while(true){
Thread.sleep(200);
}
} catch ( Throwable td){
System.out.println("restarting");
call();
}
}
public static void main(String[] args) throws Exception{
Thread a = new Thread( BrokenThreads::call);
a.start();
Thread.sleep(500);
System.out.println( Arrays.toString( a.getStackTrace() ) );
while(v[0]){
a.stop();
System.out.println(a.getStackTrace().length);
v[0] = a.isAlive();
}
System.out.println("finished normally");
System.out.println( Arrays.toString( a.getStackTrace() ) );
}
}
Note that "getStackTrace" takes time, and you can see the stacktrace accumulate as recursive calls are made, until two stops happen quick enough to end the thread.
This uses two techniques to see if the thread has stopped. isAlive and the depth of the stack trace.
I think the question describes a scenario that is the reason why Thread.stop() is deprecated since ages now, but was not yet removed … just to have a 'last resort option', to be used only when being really desperate and being aware of all the negative impact.
But that call to Thread.stop() must be build into the code somehow, same as any alternative one may think about – so why not just fix the code for the thread? Or, if that is not possible because that code comes with a third party library without source code, why not replacing that library instead?
Ok, during testing, your own code may go wild, and you need an emergency break – for that, Thread.stop() is still good enough if you do not want to kill the whole JVM (what would be the better option in most of the cases). But again, you have to build this into the code before you start the test …
But in production, there should never be a thread that does not stop when receiving an interrupt. So there should be no need for a replacement of Thread.stop().
This can potentially open a can of worms like memory access violations which will kill the JVM itelf.
What you could do is isolate the thread, running .finalize() on it, then forcing the JVM to run GC operations such as Runtime.gc(), System.runFinalization() while forcing interruptions on that particular thread in order to bypass it's resurrection behavior.
I think .finalize() is effectively deprecated since java11 or maybe sooner, so it probably won't help you much.
If you really want to secure your runtime during it's operational cycles, your best bet would be to find a way to essentially map out your configuration before you start it, and have monitoring tools set up which cross-check against that map and monitor the integrity of your runtime while looking for injected classes and/or threads. ... this is assuming of course, you're attempting to guard against "virus-like" attacks in your jvm ... which is not exactly unheard of but still pretty rare.
If you're running some code off the internet, you could simply solve the issue with a call hierarchy inspection and figure out what spawns that problematic thread.
Note: If that invasive thread is calling native dll code which is looping back into it's caller, then your JVM will crash if you mark sections of it's address space as garbage collected.
We are unfortunately stuck for the medium term with having to call a method that can sometimes never return, and forever freeze the thread that called it. Fortunately that actual call interacts with little else in the system, and returns no value. So we're thinking that until we can fix the offending code, we need to run the invocation in a separate thread that we can monitor and interrupt if it exceeds a timeout.
Clearly smarter people than I have already solved this problem and left their gifts in the concurrent package, and since this will be my first use of anything in the concurrent package, I'd just like to confirm that I'm picking the best approach.
So I'm thinking I'd get an ExecutorService by calling Excutors.newSingleThreadExecutor, submit a Runnable to it, and then call the overload of Future.get() that accepts a timeout as a parameter.
The actual task to perform is just to call a single void method on an object that I can pass into the constructor of the Runnable.
If this is the right approach, or close, I'd also really appreciate a short code sample if you're feeling generous with your time. :)
Thanks
Clearly smarter people than I have already solved this problem
Actually its not really solved IMHO.
To interrupt a task it has to be well behaved and check the interrupt or it won't actually stop. However, if its well behaved its unlikely to need to be killed in the first place.
You can use the deprecated Thread.stop() if you are sure there is no possible side effects. This requires using a plain Thread. Its not ideal even if you "know" this shouldn't cause a problem and again using a flag to stop the task is preferred.
We run an AI programming competition in which contestants will code an AI that runs on the JVM using our API we provide them. We put them into a sandbox by limiting what they can do with a SecurityManager, and during runtime they simply set several flags which are their decisions. The only interaction between our system and their AI is through these flags, so there are no bad effects on us if their thread were to suddenly die.
When an AI computes far too long, we would like to shut down their thread. However, we can't find a way of guaranteeing that we will destroy their thread. One possible reason for this is that the AI goes into an infinite loop with no blocking, making Thread.interrupt() useless. Thread.stop() is unreliable since if they are in a try catch block the ThreadDeath exception will be caught, and has no issues for us because they don't touch anything bad and we don't care if they die.
Currently we just ignore their thread and continue on without them after they time out, but their infinite loop will continue processing in the background until the JVM dies. This is unacceptable to us because we will be running matches in the background on a web server 24/7, so we want as much stability as possible. One thought has been to run each game in a separate JVM, but that is far more complex than we would like to get.
Is there any sure fire way to destroy the thread?
Provide them with a method they MUST call on a regular basis, even during their computation. If you judge they are 'dead' make the method sleep forever. Obviously his will not work if they are truly dead but you should catch most issues.
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop%28java.lang.Throwable%29
Pass in a custom subclass of Throwable that they can't know about, and you can check their code with the regex: /catch\s*(\s*Throwable/ to ensure that they don't catch Throwable anywhere.
In general, no, you should not stop an arbitrary thread in a JVM (thus the methods are deprecated). The root of the problem is that you have no idea where in the system the thread is when you kill it. In the worst case it could be in the middle of a synchronized block inside the the JVM's infrastructure that is unprepared for an unexpected exception to be thrown. (Its nearly impossible to write robust synchronized code that can be killed by an exception at arbitrary points.)
See the highly-rated answer on this question for more details:
Are java app servers able to destroy threads? If yes, how?
You might be able to get away with a cooperative design where you ask the AI thread to exit. If it does, then you're good. If it does not, then you need to restart the JVM.
After trying several things, we came to the conclusion that there is no guaranteed solution. By calling stop() on a thread, that thread is capable of catching the ThreadDeath throwable and ignoring it entirely. Thus, if it's in a while loop continuously catching it, or if it calls a method recursively that catches it, it is not guaranteed that you can kill it.
Since we didn't have any control over the code that would be running in that case, and that code was not necessarily in Java (we were also supporting Jython), the best solution we could come up with was spawning a thread that went into a loop that continuously called suspend() and then stop() on the thread. The result worked for most cases, but occasionally was unable to kill a malicious thread.
I have a program where I compile java code a user types into a text field, and then run it. A run the code in a seperate thread, so that the GUI they use to input the source code doesn't get locked up.
The GUI has an abort button that should stop the thread. My issue is that I need to stop the compiling thread no matter what is going on inside of it, which means I must account for a case where the thread is caught in an infinite loop (due to user error), and it cannot properly end itself using a safe flag. I've read up on many solutions that involve using a flag of some kind, but they aren't available to me because of this looping issue. I need to have the thread stop and the memory it's using freed (I can't just let it sit in the background forever, unless that is the only solution left). Any advice or alternative solutions? Hopefully some fresh perspectives could help squash this issue.
Edit:
Here's a sample bit of user submitted code:
public class RunMe extends SomethingThatRuns {
public void run() {
int i = 0;
while (i = 0) {
//Prepare to get stuck!
}
}
}
I'll compile this class, and then run it. This is where it will get stuck, and the run() method can never finish, or even loop to check a flag.
You can run it in a new JVM so you can kill it when you want.
Thinking about security this may be a good thing to do too.
Call stop() on the thread.
Yes, this is a deprecated method. However, it really shouldn't be "deprecated", it should be "dangerous." In some circumstances, however, there's really no choice but to use it, and the invocation of an "agent" provided by a user is one of those cases.
Make sure that your program doesn't use any data that are manipulated by this user thread; or, if you do, devise some transactional mechanism to exchange data safely between the threads.
Even this method isn't guaranteed to terminate the thread. For example, the user can catch the resulting Throwable and ignore it. Or, the thread implementation might not respond to stop() calls if the thread is in some native code. But it's your best chance.
The core issue here is the fact that the code even allows an infinite loop to be entered as part of user error. Fix that, and everything else will become easier to deal with.
Properly-behaving threads should usually terminate themselves gracefully when there's no work to do (or return quietly to a thread pool to ask for more work, if that's your application's design). If you feel like you need to have one thread forcefully kill another then you've likely got a fundamental design issue. It's fine to have one thread tell another, "Hey, you should terminate now so that I can join with you..." because that allows your threads to clean things up as they finish. Forcefully destroying threads just isn't the right way to manage these situations.
You can use them to insert a interrputed check in every loop and maybe in other places too.
I can see two options:
As you compile the user code you can edit it before. You may use
ANTLR to parse and modify the code.
There are bytecode manipulation frameworks like ASM that allow you to manipulate code that is already
compiled.
I don't think it is easy but it might be a way.
interupt(); the Thread in the gui
and in the code that the thread runs regularly check for Thread.interrupted() and throw an exception when you do especially inside loops
At a high level, you are asking how one thread might go about stopping another thread. To that end, see this SO question Stopping a Thread in Java?.
I am currently using JMX to manage and monitor a huge migration process which is executed within a Java class.
I would like to be able to abort and kill the process when I needed, e.g. customer/time required, or some dead loop happens within a single migration.
Here, we call abort a gracefully way to kill a thread by setting up a boolean flag and once every loop will check the flag first and then decides whether to proceed or not. This has been implemented without any issue.
However, I am having troubles with kill the thread. My colleague had suggested me to override the finalize() method and try to kill it within it. However, what I have found online is this method will not be able to destroy the object and it is recommned to be called by GC but the user instead.
I guess the theory is OK that as long as the object is destroyed, no more process will be able to happen. I am just not sure whether this is able to be implemented in JAVA or not.
Also, I would like to know, is there any other ways that you guys can give me a hint.
Would be very appreciate your help.
P.S: by relating to JMX, doesn't mean it really has to do with JMX, it just I would like this killing command is coming from the JMX console client.
It's a bit hard to understand what you are saying, but I don't think that finalize is going to be any help.
A live thread (i.e. one that has been started and has not yet terminated) is reachable by definition, and therefore won't be garbage collected. So adding a finalize method to it won't have any affect.
If the object you are talking about is not the thread, adding a finalize probably won't help either:
If the thread's runnable (or whatever) has a reference to the object, that will stop it from being garbage collected.
If it doesn't, and the object does become unreachable, the finalize method won't run until after the GC has decided to collect the object ... and that may never happen.
Even if the finalize method did get called, what could it do? You've already told the thread to shut down ... and nothing has happened.
The real problem here seems to be that the thread is not responding to your "graceful shutdown" flag.
I'd try to fix this by using Thread.interrupt() and Thread.isInterrupted() rather than a custom flag. This has the advantage that an interrupt will also unblock things like Thread.sleep Object.wait and certain I/O operations.
If the thread is blocked trying to talk to some external service via a socket or pipe, you could unblock it by closing the socket and/or stream. This of course assumes that your shutdown code can get its hands on the reference to the Socket or Stream object.
If those approaches failed, I'd consider pulling the plug on the entire application by calling System.exit() ... if that's a reasonable thing to do.
If you are totally desperate (and a little bit insane) you could consider using the deprecated Thread.abort() method. But there is a distinct possibility that that would leave your entire application in a broken and unresponsive state. So I would NOT recommend this approach.
The other possibilities to consider are:
that the Thread has actually responded and exited, but your shutdown code didn't notice,
that the Thread died before you tried to shut it down it, and your shutdown code didn't notice,
that the Thread is deadlocked, or
that there is some long running (but not infinite) loop in the runnable needs to be modified to check the "you die now" flag more often.
Some of these things you could be diagnosed by attaching a debugger and taking a thread dump.
I think you said that you saw advice to the effect that it was a BAD IDEA to call System.gc(). This is good advice.
You should perform certain task in finally which you want to perform when method exits in any condition. Most preferable example people give about this is cosing database connection.
Yes it is recommended to leave Garbage Collection on JVM.
JVM takes care of destrying objects.