This question already has answers here:
Are Thread.stop and friends ever safe in Java?
(8 answers)
Closed 7 years ago.
I created a following Class named as ThreadClass (which is a thread as you can see),its structure is something like the following
class SomeTask implements Runnable
{
boolean someCondition=true;
public void run() {
try
{
while(someCondition)
{
//Here goes the Process Code
}
}
catch(Exception errorException)
{
//Catching the Exception
}
finally
{
////I expect that this finally should run every time ,whatever happens in the world
}
}
}
My question is about the finally block and the stop() method
As above class is implementing Runnable, so I can create the object of this class and start a thread of it by calling start() method.I am also aware of the fact that I can stop this thread by using stop() (Yes , I know it is deprecated) method .
What I want to clarify myself is that, if somehow I need to call the stop method on the ThreadClass's object, then can I rely on the finally block to execute even if the thread is stopped by calling stop() as I am doing some important closing things in the finally block.
Thread#stop works by throwing a ThreadDeath exception, it doesn't obliterate the thread instantaneously the way System.exit blows away the JVM. ThreadDeath can even be caught, although that's not a good idea. So try blocks are still relevant.
However, complicating this is that if the thread has stop called on it multiple times then, if the second stop is called when the thread is in a finally block then it could be thrown from the finally block so that the finally block would not complete then. And if the thread's cleanup takes a while then it might be likely that stop could be called more than once on it.
Or even if you only call stop once, if at the time that stop is called the thread happens to be already executing its finally block, then the stop would interfere with completing the finally block.
This is similar to what the technotes on Thread primitive deprecation point out:
1) A thread can throw a ThreadDeath exception almost anywhere. All synchronized methods and blocks would have to be studied in great detail, with this in mind.
2) A thread can throw a second ThreadDeath exception while cleaning up from the first (in the catch or finally clause). Cleanup would have to repeated till it succeeded. The code to ensure this would be quite complex.
So there are some cases that are problematic, it would be very difficult to make sure cleanup gets done properly. James' comment is correct, if at all possible you should use interruption for this kind of thing so that the thread can reliably finish its business.
Related
This question already has answers here:
Why invoke Thread.currentThread.interrupt() in a catch InterruptException block?
(5 answers)
When does Java's Thread.sleep throw InterruptedException?
(8 answers)
Closed 1 year ago.
I am aware that ignoring an InterruptedException is actually a bad practice. But let's assume in my case it is necessary: it is a utils method in a deep place, which is called by different threads. Please also assume it is not possible to rethrow.
If my only option is to tell the system "ok, I will not sleep any further, but I cannot kill this thread myself. I will finish my job and hope that my caller takes care of your interruption request", is this the correct way of doing it?
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// ignore
Thread.currentThread().interrupt();
}
Does the method interrupt() do anything else other than resetting the interrupted flag?
Please also assume it is not possible to rethrow.
Impossible; you can always rethrow. throw new RuntimeException("unhandled", e); is never a compile time error - that should be your default choice for "I have no idea what this exceptions means or I cant be bothered to handle it". It's perfectly fine: It ensures that the code will be rolled up properly, you want that to happen when exceptions you can't handle / weren't expecting (heh) occur.
However, in this case, uniquely, 'I did not expect it' also means it cannot possibly happen.
InterruptedException
Note that InterruptedException cannot ever happen unless some code is explicitly doing it. You do not get interrupted when the system is running low on resources and needs you to clean up. You do not get interrupted because some code in java core or any third party library decided to interrupt you for funsies. You do not get interrupted when the user hits CTRL+C, or goes into the task manager and clicks 'end process'.
There is only one way to be interrupted, and it is when some java code running in your JVM process runs: yourThread.interrupt();.
Presumably, there are only two options:
[A] You never do this. The point is moot. Rethrow that thing using throw new RuntimeException(e); - you're writing code that is literally going to never ever run, stop worrying about it.
[B] You invoked interrupt(), explicitly. I assume it wasn't because the cat strolled on the keyboard :) - You had some intent by doing it. So, what is the intent? Whatever you intended to happen, program it in the catch block. The usual options are either to abort a thread entirely (so, just return;), or if you have a loop that sleeps, checks something, sleeps again, etc - to recheck (a poor man's wait/notify setup, in other words), or to re-read some configuration or otherwise re-perform some initialization procedure. It's up to you. There is no described style or rule.
Does the method interrupt() do anything else other than resetting the interrupted flag?
Yes, it returns true or false depending on whether it was up or not. But this is completely pointless. Everything in java that can throw InterruptedException +lowers that flag first_. There is therefore absolutely no point whatsoever in lowering the flag in the catch block - it has already been lowered if you ever get there. You EITHER get the flag raised on you, OR you get an InterruptedException (the flag is there because not everything throws InterruptedEx). Note that if your thread is sleeping due to some sleeping op that is not declared to throws InterruptedException, then it may interrupt or not - it depends on the OS capabilities. For example, if you're waiting for network traffic (e.g. calling read() on an InputStream derived from a java.net.Socket or whatnot), then interrupted the thread may either do nothing at all other than raise the flag, or, it will actually end up shutting down the threadsleep. In that case, the code in that InputStream will lower the flag and ends up throwing some sort of IOException (because it can't throw InterruptedException; InterruptedException is checked, and read() doesn't declare it).
Note that if the flag is raised, and you invoke any method that is specced to throw InterruptedException, said method will act IMMEDIATELY, it never goes to sleep in the first place. It lowers the flag and throws InterruptedException, instantly.
Therefore you rarely need to check the flag - very few threads lack a looping construct and very few threads will chug on for a long time without ever invoking anything that will end up invoking Thread.sleep() or obj.wait() somewhere along the line.
NB: The intent of the interrupted() method is to use it as the sole condition in a busy loop that doesn't otherwise call any code that would throw InterruptedException. e.g.:
while (!Thread.interrupted()) {
doSomethingThatNeverSleeps();
}
that'd be the whole body of your run() method. That will keep running forever and make your CPU fans make the laptop take off, at least until some other code tells the thread to call it a day by invoking .interupt(). As I said, rare that you need this construct, but that's what it is for.
I have implemented a connection check thread. When I have created a heavy traffic I have realized that there are many "ConnWatchdogThread" instances.
I think "continue" statement triggers the interrupted thread live and in that case new "ConnWatchdogThread" is created. If so how this happen? How thread is interrupted?
private class ConnWatchdog extends Thread {
public ConnWatchdog(){
setName("ConnWatchdogThread");
}
private void checkConnections() {
//connection check
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(checkPeriod);
} catch (InterruptedException e) {
// e.prinstackTrace()
continue;
}
try {
this.checkConnections();
} catch (Throwable t) {
}
}
}
}
Interruption happens when the interrupt method on the thread is called. It's not shown in your example what is doing the interrupting. Here's an example of using interrupt.
The continue advances control to the next iteration of the loop. So when something calls interrupt on your thread while it's sleeping, it bails out of the sleep (clearing the interrupt flag), then the continue sends it back to the top of the loop and it goes to sleep again, which seems pointless.
Nothing in the code shown causes a new thread to be created.
It would be more normal to use the interruption to exit the while loop and cause the thread to terminate. Using interruption for things other than thread-cancellation is not recommended (Java Concurrency in Practice, 7.1, page 138):
There is nothing in the API or language specification that ties interruption to any specific cancellation semantics, but in practice, using interruption for anything but cancellation is fragile and difficult to sustain in larger applications.
The only way to create a new Thread is with new Thread(...). Your continue is causing interrupt to be ignored and for it to sleep a little longer.
Interrupt is a special flag (but basically still just a flag) When you interrupt() a Thread it will cause some methods to throw an InterruptedException even if they are blocking. Once triggered the flag is reset.
It is generally a bad idea to ignore exception/error thrown esp in code which is not working perfectly.
Your not showing the code that uses this class. No way to say what is making the instances. Continue wont do it. In fact can remove continue from your code in the ConnWatchdog first try-catch and it will work just fine.
Post your code that is calling ConnWatchdog / instantiating it to see full picture. Is that in a loop?
What is the best way for a worker thread to signal that a graceful shutdown should be initiated?
I have a fixed size thread pool which works through a continuous set of tasks, each lasting no more than a few seconds. During normal operation this works well and chugs along with its workload.
The problem I am having is when an exception is thrown in one of the threads. If this happens I would like to bring the whole thing down and have been unable to get this working correctly.
Current approach
The naive approach that I have been using is to have a static method in the "Supervisor" class which shuts down the thread pool using the standard shutdown() and awaitTermination() approach. This is then called by any of the "Worker" classes if they encounter a problem. This was done rather than propagating the exception because execute() requires a Runnable and the run() method cannot throw exceptions.
Here is some pseudo code:
// Finds work to do and passes them on to workers
class Supervisor {
ThreadPoolExecutor exec;
static main() {
exec = new FixedThreadPool(...);
forever {
exec.execute(new Worker(next available task));
}
}
static stopThreadPool() {
exec.shutdown();
if(!exec.awaitTermination(timeout_value)) {
print "Timed out waiting on terminate"
}
}
}
class Worker {
run() {
try {
// Work goes here
} catch () {
Supervisor.stopThreadPool()
}
}
}
The effect that I am seeing is that the threads do pause for a while but then I see the timeout message and they all resume their processing. This pattern continues until I manually shut it down. If I put a call to stopThreadPool() in the main method after having broken out of the loop, the shutdown happens correctly as expected.
The approach is clearly wrong because it doesn't work, but it also feels like the design is not right.
To reiterate the question: What is the best way for a worker thread to signal that a graceful shutdown should be initiated?
Additional information
The questions I have looked at on SO have been of two types:
"How do I kill a thread in a thread pool?"
"How do I know all my threads are finished?"
That's not what I'm after. They also seem to exclusively talk about a finite set of tasks whereas I am dealing with a continuous feed.
I have read about an alternative approach using exec.submit() and Futures which puts the onus on the supervisor class to check that everything's ok but I don't know enough about it to know if it's a better design. The exception case is, well ... exceptional and so I wouldn't want to add work/complexity to the normal case unnecessarily.
(Minor side note: This is a work project and there are other people involved. I'm saying "I" in the question for simplicity.)
You are not that far from the correct solution, the problem is that you need to handle the interruption caused by the shutdown call properly. So your thread's run method should look like this:
run () {
try {
while (Thread.interrupted() == false) {
doSomeWork();
}
} catch (Exception e) {
myExecutor.shutdown();
}
}
Note that I explicitly used the shutdown() without awaitTermination() because otherwise the waiting thread is the one that keeps the Executor from properly terminating, because one thread is still waiting. Perfect single-thread deadlock. ;)
The check for interruption is by the way the hint on how to kill a thread gracefully: get the run method to end by either setting a running boolean to false or by interrupting, the thread will die a moment later.
To check if all of your threads have terminated (= are just about to end their run method), you can use a CountDownLatch for a simple case or the CyclicBarrier/Phaser class for more complex cases.
There are 2 problems here:
If you intend to just force a shutdown on any exception in a worker, then you do you use shutdown() and await counterparts. Just force it using shutdownNow and you should be good. shutdown does a graceful shutdown.
try to break your for loop when such a thing happens. The best way to do it is have a try catch in your for loop around the execute call. when an exception happens in a worker throw an unchecked exception and catch it in the for loop. Terminate the for loop and call your method to force shutdown on executor. This is a cleaner approach. Alternately you can also consider using consider a handler in your executor for doing this.
I am realizing that if a exception are raised inside(or not, but should be related to) my runnable's run method, all my future tasks will not be run.
So my question is: How can I recover from such a exception (where to catch it)?
I have tried this:
ScheduledExecutorService Exception handling
If i do a while loop to catch the exception, the future tasks are still not executed. I also tried to schedule the catch, no help either.
I tried to put a huge try/catch to wrap all the code in run method but it seems to be not catching anything, and some exception are still not catches and causing all my future tasks to not run.
In the executor framework, you are giving control of running a job away from one main application thread to a thread pool thread. A thread submits the work through a schedule, or submit method is returned a Future object that allows it to get information through a get method. The get method will throw an executor exception whose cause is probably the exception that your code inside the runnable threw. If the main thread does not do that it will never see that exception, so it really depends on your application logic flow.
Another thing also to mention, if you try catch all, what do you mean by that if you are doing something similar to
try {
....
}
catch(Exception e) {
.... }
you are really not catching errors in your app (throwable is the father of Exception and Error) so you might have some static initializer error (an exception caught in a static block)
Again it all depends on how you want exception handling to happen you have full power,
Thank you
I have the main thread of execution which spawns new threads. In the main thread of execution in main() I am calling Thread.sleep(). When do I get an Unhandled exception type InterruptedException?.
I am unsure of why am I getting this. I thought this was because I needed a reference to the main thread so I went ahead and made a reference to it via Thread.currentThread().
Is this not the way to have the thread sleep? What I need to do is have the main thread wait/sleep/delay till it does it required work again.
What you see is a compilation error, due to the fact that you didn't handle the checked exception (InterruptedException in this case) properly. Handling means doing one of the following:
1) Declaring the method as throws InterruptedException, thus requiring the caller to handle the exception
2) Catching it with a try{..}catch(..){..} block. For example:
try {
Thread.sleep(1500);
} catch(InterruptedException e) {
System.out.println("got interrupted!");
}
InterruptedException is used to indicate that the current thread has been interrupted by an external thread while it was performing some blocking operation (e.g. interruptible IO, wait, sleep)
At the line where you're definition of main starts, just include throws Exception. I too was facing similar problem, and this helped. After this inclusion, you need not include the Thread.sleep(xx); inside a try-catch statement
Thread.sleep(t);
This is how you can make your thread wait. where t is in milliseconds.
It is working fine in my main method, so to find out your problem it would be better if you can provide your code here.