How Java thread.stop() work? - java

I am actually looking for an easier way to kill the thread not matter where the thread is running at. But most of the solutions in internet point me to use boolean flag to control the execution of the thread, if I want to stop the thread then set the boolean variable to false.
But what if the task that in the runnable is a LONG linear task, which mean the task is not repeating? In that case, it is not so easy to create a 'while' loop to cover the whole block of task.
It is really so temptative to use Thread.stop but the warning "Deprecated" seem like quite dangerous to use. I have read through this article
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
but I can't understand
If any of the objects previously protected by these monitors were in
an inconsistent state, other threads may now view these objects in an
inconsistent state. Such objects are said to be damaged.
What does the "inconsistent state" mean? I appreciate if anyone can explain about this.
I want to extend my question to a more lower level of view, let say i = i + 1; in JVM (perhaps assembly language alike), maybe this Java statement will be split into few smaller instructions, for example like move i ; add i ; get i into memory 0x0101 (This is an example! I totally don't know assembly language!)
Now, if we call thread.stop, where actually will it stop at? Will the thread stop after a COMPLETED Java statement, or could be in the middle of the "assemble language"? If the answer is the second, could it be reason that we said
Such objects are said to be damaged.
?
Ok, my question is kind of confused, hope someone can understand and explain. Thanks in advance.

"Damaged object" is a high-level concept, it doesn't happen at the JVM level. A programmer designs his class with thread safety in mind by guarding critical sections with locks. It is an invariant of his class that each critical section either runs in full, or doesn't run at all. When you stop a thread, a critical section may have been interrupted in the middle, so disrupting the invariant. At that moment the object is damaged.
Stopping a thread conceals many more dangers, like no cleanup performed, no acquired resources released, etc. If a thread doesn't give up what it is doing, there is no way to make it stop without compromising the entire application.
In practice, whenever one faces the need to run alien code that may need to be forcefully aborted, this must be done in a separate process because killing a process at least performs OS-level cleanup and does a much better job of containing the damage.

The "inconsistent state" means state of data as your application cares about, state that your application logic have carefully produced by making your application thread-safe with locks/monitors etc.
Imagine you have this simple method:
public synchronized void doSomething()
{
count++;
average = count/total;
}
This method, along with other methods are synchronized, as multiple threads are using this object.
Perhaps there's a
public synchronized AverageAndCount getMeasurement()
{
return new AverageAndCount(average, count);
}
This assures that a thread can't read an incomplete measurement, i.e. if the current measurement is in the process of being calculated inside e.g. doSomething(), getMeasurement() will block/wait until that's finished.
Now, imagine the doSomething is run in a thread, and you call .stop() on that thread.
So the thread might be stopped right after it performs count++;, the monitor that's held is unlocked and the method terminates and average = count/total; is not executed,
That means the data is now inconsistent. Anyone calling getMeasurement() afterwards will now get inconsistent data.
Note also that at this point it is not very relevant whether this happens at a java statement level, or at a lower level, the data can be in an inconsistent state that you can't reason about in any case.

I'm no expert but this is what I think.
If you use Thread.stop() you cause the ThreadDeath exception that will cause all monitors to be released.
Since you provoke an exception you are applying an unnatural behaviour to the state of things.
Other threads relying on those monitors could enter in an inconsistent situation because they were not expecting it. And I don't think you can even anticipate the monitors releasing order.

I believe the concern is that the thread may be in the middle of a synchronize block performing multi-step updates to an object's members. If the thread is stopped abruptly, then some updates will have occurred but not others and now the object's state may render it unusable.
I have my doubts that the ThreadDeath handling will release a Lock backed by the AbstractQueuedSynchronizer which could leave the application on the path to a sort of deadlock.
At any logical point in your long sequence of code you can simply add:
if (Thread.interrupted()) {
throw new InterruptedException();
}
...this will exit execution at this point if it is determined that Thread.interupt() was called on the Thread executing the long running task.

It's not clear way to stop the thread.actually deprecated the stop() method whenever run() method is completed or any exception is occurred then thread is stop.by using the boolean flag variable .Bydefault "false"

Related

Reliably stopping an unresponsive thread

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.

Why does Thread class has static methods when we have currentThread() method?

Thread class has many static methods that are called by class name. Some of them are:
But yet, we are provided with method currentThread() that returns currently executing thread object. Some are:
Unfortunately, this created confusion in my head. When I think of a method I want, I have no clue whether I would found it as static or instance. So why did they make such two approaches?
I mean, couldn't they all be grouped in same 'calling'? For example why is sleep() static and not instance method called with Thread.currentThread().sleep()? Another weird example is between interrupted() and isInterrupted() defined in different manner. They do exactly the same thing, just interrupted() additionally clears interrupted flag. Has anyone logic answer to this, so I have no struggle where to find each method?
It's tricky; the answer is different for each method. Let's go through the ones you named:
Thread.sleep
Imagine I called: someOtherThread.sleep(1000L);. What would this mean? Surely that ought to mean: Sleep that other thread, not my thread. Except that's not something java offers: You can sleep your own thread, but you cannot arbitrarily tell some other thread to freeze like they're doing a mime act, mid execution of some arbitrary command. For example, if that thread is currently blocked on, say, waiting for the OS to deliver some bytes from a file read, that definitely cannot just fall asleep, and there are many, many other scenarios where a thread cannot do that.
Thus, java does not offer this functionality - you can't sleep other threads. Only your own. There are two different ways to make this at least somewhat clear in API design:
The first is to have sleep be an instance method (thus, you'd have to write e.g. Thread.currentThread().sleep(1000L);), and spec the method that it will guaranteed, always, immediately throw an IllegalStateException if you invoke it on any thread except your own. This means a compile/write-time detectable error condition would only be caught at runtime (this is bad; catching a problem earlier is obviously better than catching it later), it makes the code you'd have to write to sleep needlessly longer, and the existence of a sleep method you can invoke on thread instances sure suggests that you can sleep other threads. It'd just be crappy API design.
The second is to make sleep static.
Think of it this way: java.lang.Thread is a container for two mostly unrelated batches of methods: One is a set of methods you can use on threads (those'd be the instance methods). The other is a bunch of thread and flow related primitives, such as 'sleep', 'yield', and interrupt interaction. They just happen to be shoved into the same class.
interrupt
This is probably the trickiest. Unlike sleeping, you can in fact ask another thread's interrupt flag status.
The reason there are two methods are because of the more or less intended API design of the interrupt system.
The interrupt system is designed as follows:
If you want some thread to stop what it is doing for some unspecified reason (for example, you want it to re-check some condition, or just cease running, or anything else you can think of) then you need a mechanism to signal this. In particular, you'd want such a mechanism to ensure that any interruptable blocking operations, such as Thread.sleep(100000L) are interrupted. In other words, you can't just say: Whatever, it's up to the code itself, just, um, make an AtomicBoolean and check it a lot.
That's where the 'interrupt' system comes in. The idea is:
To interrupt any thread, raise its interrupt flag, with thatThread.interrupt();
All methods that do interruptable things should check this flag. The procedure is: If it is raised, then [A] clear it, and [B] handle the interruption, doing whatever the programmer intended to happen upon interruption (just stop running, or re-check some condition, re-read some config file, who knows - it's programming, whatever you want it to mean). If you CAN handle the notion of aborting some operation, but you CANNOT handle it, then instead clear that flag and throw InterruptedException, so that the caller can handle it.
As a result, any code that knows what 'I was interrupted!' means should BOTH check the flag (especially if that code has an event loop, which most thread-based code does have), AND catch InterruptedException from any method specced to throw it, and react in the exact same way to either catching that exception or having Thread.interrupted() return true.
Things go all sorts of wrong if you handle the fact that the interrupt flag is up, but you do NOT lower it. For example, if you abort your CPU-bound bitcoin mining or whatnot and just return back to your caller whilst leaving the flag up, then the next time caller invokes Thread.sleep, thread.sleep will notice the flag is up and IMMEDIATELY exit, not sleeping at all (exit by throwing InterruptedException, to be specific). That isn't intended. Hence why it is important that if you respond to an interrupt, you lower that flag.
So, let's go back to API design. There are two strategies:
Hypothetical design A
while (!Thread.currentThread().isInterrupted()) {
mineAnotherBitCoin();
}
Thread.currentThread().clearInterruptFlag();
Design B
while (!Thread.checkAndClearInterruptFlag()) {
mineAnotherBitCoin();
}
Note how design B is conceptually a lot shorter, does not have a 'gap' between checking the flag and clearing it, and therefore is fundamentally less error prone. Furthermore, for, well, reasons, it has been decided that raising an interrupt flag is something you can do to other threads (there is no point interrupting yourself, after all), but clearing one is a thing you can only do to your own thread.
B is what java actually has, except the method is somewhat strangely named interrupted(), and not checkAndClearInterruptFlag(). If you want an explanation of why some methods in java are somewhat suspectly named, it's because java does not like breaking backwards compatibility.
Fundamentally then, while they sound real similar, isInterrupted() and interrupted() do two very different things.
isInterrupted() is to check if some thread has already been interrupted and its response to this interruption is still pending (nothing has yet handled it).
interrupted() is something you put in the condition in your while loops that define the core body of your thread implementation (your 'event loop').
*) It doesn't help that the vast majority of examples of how to make threads in java are erroneous in that they don't properly do this. They tend to be while (true) or while (!running) {} or similar, either ignoring interruptions entirely or with a handrolled interrupt-esque 'running' concept.
So how do I know where to look?
Simple enough: If it's a thing that conceptually doesn't belong to any particular thread (such as 'how many threads are active right now'), or it is a utility concept (such as 'sleep'), or it is a thing that from a VM design principle can only be done to your own thread and not to anything else, then it is a static method in Thread.
If it's a thing that does belong to a particular thread AND the VM would let you do it to other threads (such as interrupting it, asking for its name, id, or priority, getting a stack dump, freezing this thread until the other thread completes, or setting its priority), then it's an instance method.
In many ways you can reverse this logic: If you want to do some thread related business, check the Thread class for something that seems to describe what you want. Then check if the method is static or not. If it is static, you don't get to do it to any other thread (such as clearing the interrupt flag, or sleep). If it's instance, you CAN do that to other threads (such as changing its priority level).
Because you can't make another thread sleep that is not the thread you are on. Even when you call Thread.currentThread().sleep(), you are calling the static method 'sleep'. If you were to call the sleep method on a different Thread object, it would still make the current thread sleep.
If you want to make a different thread sleep, you should set a flag that the other thread reads, which causes it to sleep.

Detect java thread starting to wait and run some code

Is there any way to put any sort of event listener that will be called when some thread - for example, the current thread - stops its activity and starts waiting or terminates?
I need this for the object to be notified and release some resources, when it is not in active use in this thread but still stored in memory somewhere that prevents it from being garbage collected - otherwise I'd place that resource releasing code in finalise() method.
UPD
Use case: an object that keeps a reference to a jdbc resultset or a database connection; the respective close() or commit() should be called automatically when the object is set aside temporarily or discarded at all without requiring the program to call any sort of cleanup method.
(There is no question how do I lock the object to be accessed from only one thread at a time, it is solved.)
The distinct non-answer: wrong design point. Threads don't "own" resources.
Threads are simply "threads of execution". They run the code you tell them to run. Therefore a thread doesn't own any of the objects it comes by.
As a consequence, there are no built-in mechanisms to help with your requirement. You would have to implement something yourself, relying on monitoring threads, and their states. Which would be a hard and challenging task. Mainly because: multi threading is hard.
The serious recommendation here: step back from this design. Rather think about other, different ways to deal with such "resources".
This is indeed a wrong approach.
You can obviously lock the object and unlock it in a finally block like this:
private Lock lock = new ReentrantLock();
public void useObject() {
lock.lock();
try {
//do something with your resource.
}
finally {
lock.unlock();
}
}
This way if the thread that runs useObject terminates, it will execute the finally block, and unlock the lock that protects the resource.
But there's NO way to detect the thread is not having any activity. If the thread is preempted by the Operation System, there's no way for you to know about it. That's below the abstraction level, you as a developer, operate.
If you want to gain more understanding on how the OS works with threads, and what you can cannot do you should check out
Java Multithreading, Concurrency & Performance Optimization
course on Udemy.
It also talks about how to properly use the right locks to do this kind of safe synchronization, and get the best performance from your application when you have to share resources such as database connections.
I hope it helps

Cleanly Stopping a Thread

I've finally managed to implement Thread.interrupt() into my program instead of Thread.stop(). I am however not sure that I've done this well.
I have a class which extends Thread and declares several methods. EVERY method has been made to throw InterruptedException (Each method performs I/O intensive operations, some of which take several minutes to complete, I have therefore not used a thread-safe flag as the flag would not get checked until after the operation completed). I have also added the following code at several places within these methods to throw the exceptions:
if (this.isInterrupted()) throw new InterruptedException();
Within the run() method I execute all methods within a try/catch for InterruptedException. If caught, I execute Process.destroy() and BufferedReader.close() for my class variables.
This all works, and seems to work very well, however I have a couple of questions:
Is it correct to have more than 10 methods, all of which throw InterruptedException? Is there a better way to do this?
Is it correct to bloat the methods with checks for isInterrupted()?
At the end of the catch InterruptedException block, must I execute a 'return', or 'null' certain values to make the Thread available for GC? If I re-create the Thread it takes longer than usual to initialize.
Finally, are there any issues/enhancements related to what I've done?
Thanks in advance for your help!
Thread interruption in Java doesn't mean stopping the execution of that thread. It is not stop, it is interrupt. A thread can be interrupted when something fundamental and crucial changes, telling the thread that its execution context, its task or its enviroment changed in some significant way. A thread reaction to this message is implementation specific. It can be stop, it can be restart or any other action. A thread that doesn't handle interruptions cannot be interrupted, but its behaviour can still be altered, for example, by using a shared variable.
For example, imagine you have a number of threads, all searching through a part of a problem space for a solution. When one thread finds a solution, it can interrupt other threads, because their search for a solution is no longer relevant. A solution has already been found.
Or imagine one continuously working main thread and one network communication thread. Each time the network thread receives a messsage, it interrupts the working thread with the message. Based on what the message and the context is, the worker thread may decide what to do next. For example, if the message was "STOP", then it could stop all execution immediately. If the message was "RESET", it could start again from scratch or maybe not from scratch and reuse some previous work, based on the execution context.
Is it correct to have more than 10 methods, all of which throw
InterruptedException? Is there a better way to do this?
No, this is perfectly fine, as long as you know what you are doing. If you implement interruptions to just stop the threads, there is no need to throw InterruptedExceptions. A Thread's run() method is it's first, and the exception will not go any further the stack.
Is it correct to bloat the methods with checks for isInterrupted()?
Depending on the context. The checks would be usually added before some crucial code. Usually it is added as a first item in the loop block.
At the end of the catch InterruptedException block, must I execute a
'return', or 'null' certain values to make the Thread available for
GC? If I re-create the Thread it takes longer than usual to
initialize.
No. Once the Thread exists from the run() method, it's left at GC's mercy. Shared variables will not be GC'ed, as long as they are still referenced by other objects.

How to kill non-interruptable thread?

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.

Categories