How to handle InterruptedException of BlockingQueue? [duplicate] - java

This question already has answers here:
Handling InterruptedException in Java
(7 answers)
Closed 6 years ago.
I have a code similar to this which is inside run() method of a Runnable and multiple instances of that Runnable get launched,
do{
try{
String contractNum=contractNums.take();
}catch(InterruptedException e){
logger.error(e.getMessage(), e);
}
}while(!("*".equals(contractNum)));
Where contractNums is a BlockingQueue<String> shared by multiple threads. There are separate Runnables putting elements to this queue.
I am not sure about next steps after catching InterruptedException, should I terminate this thread by re throwing a RuntimeException ( so my while loop terminates ) or try to take next element from contractNum queue again and ignoring InterruptedException?
I am not sure if InterruptedException to be treated as a fatal condition for thread to terminate or keep it in while loop.
Please suggest.

7.1.2 Interruption policies
Just as tasks should have a cancellation policy, threads should have
an interruption policy. An interruption policy determines how a thread
interprets an interruption request—what it does (if anything) when one
is detected, what units of work are considered atomic with respect to
interruption, and how quickly it reacts to interruption. The most
sensible interruption policy is some form of thread-level or service-
level cancellation: exit as quickly as practical, cleaning up if
necessary, and pos- sibly notifying some owning entity that the thread
is exiting. It is possible to establish other interruption policies,
such as pausing or resuming a service, but threads or thread pools
with nonstandard interruption policies may need to be restricted to
tasks that have been written with an awareness of the policy.
7.1.3 Responding to interruption
As mentioned befor, when you call an interruptible blocking method
such as Thread.sleep or BlockingQueue.put , there are two practical
strategies for handling InterruptedException :
• Propagate the exception (possibly after some task-specific cleanup),
making your method an interruptible blocking method, too; or
• Restore the interruption status so that code higher up on the call
stack can deal with it.
Java Concurrency in Practice Chapter 7.
Specifically in your code you will need to make sure that if thread is interrupted your application logic is not broken.
And it is indeed better to catch your interruption exception. What to with it is up to you just try to make sure that you don't break the application logic.

It depends. Are there places where you intentionally interrupt the thread, for example to tell it to finish up (for example during shutdown)? If not, you just need to handle possible spurious interrupts that will wake up the thread. If you don't want the processing to be affected, just ignore them. They're in absolutely no way fatal exceptions, and you don't need to log them (especially as errors).

Related

Which code can swallow interruptedException?

I read concurency in practice. Now I want to understand how to handle InterrruptedException
Advices from book:
- Propagate the exception (possibly after some task-specific cleanup),
making your method an interruptible blocking method, too; or
- Restore the interruption status so that code higher up on the call stack can
deal with it.
- Only code that implements a thread's interruption policy
may swallow an interruption request. General-purpose task and library
code should never swallow interruption requests.
First two statements are clear for me but I don't understand third. Can you clarify this? Providing example will preferably.
update(thanks Shubham for the link )
The one time it is acceptable to swallow an interrupt is when you know
the thread is about to exit. This scenario only occurs when the class
calling the interruptible method is part of a Thread, not a Runnable
or general-purpose library code, as illustrated in Listing 5. It
creates a thread that enumerates prime numbers until it is interrupted
and allows the thread to exit upon interruption. The prime-seeking
loop checks for interruption in two places: once by polling the
isInterrupted() method in the header of the while loop and once when
it calls the blocking BlockingQueue.put() method.
public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
}
I don't understand the bolded text now.
Short answer:
If you can deal with the situation, it is allowed to swallow it.
The interrupted exception occurs when the process occurring in that parallel thread was cancelled, or well, interrupted. So if you are the only one interested in that fact, and you can deal with the situation of having that thread "dead", then you can swallow it.
That is perfectly possible in real life examples. The strategy depends on each situation.
ExecutorService would be an example of the third statement.
This coordinates the execution of multiple runnables(/callables) on the same "actual" thread.
If one runnable is interrupted whilst being executed, that interruption should not affect execution of subsequent runnables.
So, ExecutorService should swallow the interruption, having dealt with it appropriately from the perspective of the interrupted runnable, in order to allow reuse of the thread for the next runnable.
Suppose we write a utility code and there is some clinet code dependent upon our code. If an InterruptedException occurs, it should not be consumed in the utility method (in a try block), it should be thrown and also as InterruptedException clears the interrupt flag, it must be set again to true by invoking interrupt method.
Its the core code which needs to take care of the decision to be taken upon occurrence of an InterruptedException [update] This core code may depend upon the interrupt flag or the InterruptedException to terminate a loop, end thread's execution or any other decision.
Moreover utility or library are the low level code which is invoked from higer level client code. Low level should ideally propogate such exception to let the higher level code manage it.

InterruptedException : what causes it?

There are interesting questions and answers regarding Java's InterruptedException, for example The Cause of InterruptedException and Handling InterruptedException in Java. However, none of them tells me about the possible sources of InterruptedException.
What about OS signals like SIGTERM, SIGQUIT, SIGINT? Does pressing CTRL-C on the command line produce an InterruptedException? What else?
None of the things you list produce an InterruptedException.
The only thing that can interrupt a thread is a call to Thread#interrupt(). The JLS is relatively clear on the matter, from section 17.2.3:
17.2.3 Interruptions
Interruption actions occur upon invocation of Thread.interrupt, as well as
methods defined to invoke it in turn, such as ThreadGroup.interrupt.
See the official tutorial on interrupts for some more info as well. Specifically:
A thread sends an interrupt by invoking interrupt on the Thread object for the thread to be interrupted. For the interrupt mechanism to work correctly, the interrupted thread must support its own interruption.
...
The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
The implication is that it is an explicit flag settable only by calling interrupt(), rather than triggered by other unknown external events. This is further implied by the description of the exception in various methods that throw it, for example (emphasis mine):
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
The purpose of the interrupt system in general is to provide a common, well-defined framework for allowing threads to interrupt tasks (potentially time-consuming ones) in other threads. While you could implement similar functionality with explicit logic in your own application, having this well-defined mechanism allows independent classes (e.g. the JDK, other third-party code, other independent classes in your own code) to provide this functionality in a consistent way.
The many notes and "warnings" you see about handling InterruptedException aren't meant to imply that they can be thrown completely spontaneously, they are meant to encourage well-designed objects that can be used in contexts that are not known yet, where interrupt() would be presumed to work (so really, you do want to assume they can be thrown spontaneously if you are creating reusable objects that will be robust in future situations - i.e. you're never guaranteed that your code won't be some day used by somebody who expects interrupts to work).
For quick one-off projects you don't really need to worry about special handling for these exceptions as long as you know for certain that you aren't calling interrupt() and aren't calling something that can call interrupt(), but be aware of the implications of that in the long run, especially if you end up reusing that code in other contexts.

Thread Interrupt in java

I have the following questions, if I interrupt a thread in java, a process that is running 15 minutes, it will stop the process, stop the methods or will finish this process,and not allow others continue in line?
I have a "thread" that will call a method that will do a comparison based "access" and "postgres" after it will insert in postgres, if I want to stop the thread that called this action, she will succeed the stop the process, or wait they finish?
It will not stop the thread unless the methods executing in it are willing to terminate when they receive the "interrupt" signal. Methods that throw InterruptedException usually fall into this category. Of course, all methods in the call chain need to cooperate in one way or another.
If your code does not call "interruptable" methods or has sections that don't call them for long periods, then make them check flag Thread.isInterrupted() periodically, and terminate clean and gracefully if it ever becomes true. Same thing if you ever receive (and catch, which you should) InterruptedExceptions.
Your question can be improved, though, if your intent is more specific. I was about to explain how the "thread interrupt" protocol works, but perhaps this is not what you are looking for.
When you "interrupt" a thread, it does one of three things (which are probably the same thing behind the scenes):
If the thread is currently waiting, sleeping, or joining another thread, the interrupt will cause an InterruptedException to be thrown in the target thread.
If the thread is blocked waiting on "interruptible I/O" (that is, operations on an implementation of InterruptibleChannel), a ClosedByInterruptException will be thrown.
If it's not doing one of those things, then a flag will be set on the thread. The thread can check that flag by calling Thread.interrupted() (which will immediately reset the flag)...but if it doesn't, the next call to any_object.wait(), Thread.sleep(), or any_thread.join(), and perhaps certain other blocking methods, will throw an exception.
All these exceptions, of course, are checked exceptions...which almost invariably means that there will be an exception handler nearby (which, unless the code was designed to be interruptible, will typically just ignore the exception and try the operation again). And if the thread never waits, and never checks the interrupt flag, then interrupting it won't do much.
Also, if the thread is currently waiting on something outside the control of the JVM, the interrupt might not have any effect. On some platforms (Windows comes to mind), Java has a hard time interrupting native code.
All those caveats can be summed up as: If what you want is to kill off an unruly thread, this probably isn't the way to do it. Truth is, there isn't a decent way to kill a thread without leaving your process in a potentially wacky state. What you typically want in such cases is a separate process you can kill if it gets out of hand.
From the source:-
An interrupt is an indication to a thread that it should stop what it
is doing and do something else. It's up to the programmer to decide
exactly how a thread responds to an interrupt, but it is very common
for the thread to terminate. This is the usage emphasized in this
lesson. A thread sends an interrupt by invoking interrupt on the
Thread object for the thread to be interrupted. For the interrupt
mechanism to work correctly, the interrupted thread must support its
own interruption.

Who is calling the Java Thread interrupt() method if I'm not?

I've read and re-read Java Concurrency in Practice, I've read several threads here on the subject, I've read the IBM article Dealing with InterruptedException and yet there's something I'm simply not grasping which I think can be broken down into two questions:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
The Thread interrupt mechanism is the preferred way to get a (cooperating) thread to respond a request to stop what it is doing. Any thread (including the thread itself I think) could call interrupt() on a Thread.
In practice, the normal use-cases for interrupt() involve some kind of framework or manager telling some worker thread to stop what they are doing. If the worker thread is "interrupt aware" it will notice that it has been interrupted via an exception, or by periodically checking its interrupted flag. On noticing that it has been interrupted, a well-behaved thread would abandon what it is doing and end itself.
Assuming the above use-case, your code is likely to be interrupted if it is run within a Java framework or from some worker thread. And when it is interrupted, your code should abandon what it is doing and cause itself to end by the most appropriate means. Depending on how your code was called, this might be done by returning or by throwing some appropriate exception. But it probably should not call System.exit(). (Your application does not necessarily know why it was interrupted, and it certainly does not know if there are other threads that need to be interrupted by the framework.)
On the other hand, if your code is not designed to run under the control of some framework, you could argue that the InterruptedException is an unexpected exception; i.e. a bug. In that case, you should treat the exception as you would other bugs; e.g. wrap it in an unchecked exception, and catch and log it at the same point you deal with other unexpected unchecked exceptions. (Alternatively, your application could simply ignore the interrupt and continue doing what it was doing.)
1) If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
One example is if your Runnable objects are executed using an ExecutorService and shutdownNow() is called on the service. And in theory, any 3rd-party thread pool or thread management framework could legitimately do something like this.
2) If I'm never ever interrupting other threads myself using interrupt() ... what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need analyze the codebase to figure out what is making the interrupt() calls and why. Once you have figured that out, you can work out what >>your<< part of the app needs to do.
Until you know why InterruptedException is being thrown, I would advise treating it as a hard error; e.g. print a stacktrace to the log file and shut down the app. (Obviously, that's not always the right answer ... but the point is that this is "a bug", and it needs to be brought to the attention of the developer / maintainer.)
3) How do I find out who / what is calling interrupt()?
There is no good answer to this. The best I can suggest is to set a breakpoint on the Thread.interrupt() and look at the call stack.
If you decide to integrate your code with other libraries, they can call interrupt() on your code. e.g. if you decide in the future to execute your code within an ExecutorService, then that may force a shutdown via interrupt().
To put it briefly, I would consider not just where your code is running now, but in what context it may run in the future. e.g. are you going to put it in a library ? A container ? How will other people use it ? Are you going to reuse it ?
As others have pointed out, interrupting a thread (actually, interrupting a blocking call) is usually used for purposes of exiting cleanly or cancelling an ongoing activity.
However, you should not treat an InterruptedException alone as a "quit command". Instead, you should think of interrupts as a means to control the running status of threads, much in the same way as Object.notify() does. In the same way that you'd check the current state after waking up from a call to Object.wait() (you don't assume that the wakeup means your wait condition has been satisfied), after being nudged with an interrupt you should check why you were interrupted. There is usually a way to do this. For example, java.util.concurrent.FutureTask has an isCancelled() method.
Code sample:
public void run() {
....
try {
.... // Calls that may block.
} catch (InterruptedException e) {
if (!running) { // Add preferred synchronization here.
return; // Explicit flag says we should stop running.
}
// We were interrupted, but the flag says we're still running.
// It would be wrong to always exit here. The interrupt 'nudge'
// could mean something completely different. For example, it
// could be that the thread was blocking on a read from a particular
// file, and now we should read from a different file.
// Interrupt != quit (not necessarily).
}
....
}
public void stop() {
running = false; // Add preferred synchronization here.
myThread.interrupt();
}
The problem with the question is "I". "I" usually refers to a single instance of a class. I mean by that, that any particular piece of low-level code (class) should not rely upon the implementation of the entire system. Having said that you do have make some "architectural" decisions (like what platform to run on).
Possible unexpected interrupts coming from the JRE are canceled tasks in java.util.concurrent and shutting down applets.
Handling of thread interrupts is usually written incorrectly. Therefore, I suggest the architectural decision to avoid causing interrupts where possible. However, code handling interrupts should always be written correctly. Can't take interrupts out of the platform now.
You could learn this by creating your own thread class (extending java.lang.Thread) and overriding interrupt() method, in which you record the stacktrace into, say, a String field, and then transfer to super.interrupt().
public class MyThread extends Thread {
public volatile String interruptStacktrace; // Temporary field for debugging purpose.
#Override
public void interrupt() {
interruptStacktrace = dumpStack(); // You implement it somehow...
super.interrupt();
}
}
As already mentioned, another library can interrupt your threads. Even if the library doesn't have explicit access to the threads from your code, they can still get the list of threads that are running and interrupt them that way with the following method.
I think I understand why you are a bit confused about interruption. Please consider my answers in line:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
Firstly you may interrupt other threads; I know that in JCiP it is mentioned that you should never interrupt threads you do not own; however, this statement has to be properly understood. What it means is that your code which might be running in any arbitrary thread should not handle interruption because since it is not the owner of the thread it has no clue of its interruption policy. So you may request interruption on other threads, but let its owner take the course of interruption action; it has the interruption policy encapsulated within it, not your task code; at least be courteous to set the interruption flag!
There are many ways why there could be interruptions still, may be timeouts, JVM interrupts etc.
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need to be very careful here; if you own the thread which threw InterruptedException (IE), then you know what to do upon catching it, say you may shutdown your app/service or you may replace this killed thread with a new one! However, if you do not own the thread then upon catching IE either rethrow it higher up the call stack or after doing something (may be logging), reset the interrupted status so that the code which owns this thread, when control reaches it, may learn that the thread was interrupted and hence take actions as it will since only it knows the interruption policy.
Hope this helped.
The InterruptedException says that a routine may be interrupted, but not necessarily that it will be.
If you don't expect the interrupt then you should treat it as you might any other unexpected exception. If it's in a critical section where an unexpected exception could have heinous consequences, it might be best to try and clean up resources and gracefully shutdown (because getting the interrupt signals that your well-engineered application that doesn't rely on interrupts is being used in a way it wasn't designed, and so there must be something wrong). Alternatively, if the code in question is something non-critical or trivial, you might want to ignore (or log) the interrupt and keep going.

java & threads: interrupted exceptions & how to properly use BlockingQueue's take() method

What exactly happens when there is nothing on the queue and a take() is called. The API says the method will wait but does that mean the CPU spins checking for empty/not empty until an item is on the queue or does it mean that the thread yields and will be awoken by an interrupt? If it is the case of the former, I would probably want to see if the queue is empty and if it is call thread.yield() to give up processor time. My question is really do I need to call yield or does some inner mechanism handle that for me?
Secondly, what is the interrupted exception meant for? If I understand correctly it means that if thread A is executing this method and is waiting for input and another thread B calls threadA.interrupt() then thread A will catch the interrupted exception and presumably pause execution, if it is nice. Is that the correct way of thinking about it?
Note that BlockingQueue is an interface. So what follows is implementation dependent. If you look at the source code for (say) LinkedBlockingQueue, the source for take() calls lockInterruptibly() on a RentrantLock. From the doc for this:
If the lock is not available then the
current thread becomes disabled for
thread scheduling purposes and lies
dormant until one of two things
happens:
* The lock is acquired by the current thread; or
* Some other thread interrupts the current thread, and interruption of
lock acquisition is supported.
I suspect there's be some wait()/notify() or similar going on. Will it spin the CPU ? No (check via top or similar)
Re. your question on interrupts, the Java Specialist newsletter had a very interesting article on interrupt() and catching/handling the InterruptedException.
Read the article, but essentially if you catch the exception, you reinterrupt:
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); // very important
break;
}
The wait() call does not spin, it typically uses OS services to wait for an event/condition - which puts the thread to sleep until the condition/event is signaled again. No processor time is used while waiting.
You typically get the interrupted exception if the thread is blocking in a wait() call, and another thread calls interrupt() on that blocking thread, just like you said.
It is considered a bad practice to call yield() as it cannot ensure niceness - you may call it and the scheduler instantly returns to your thread as it were a no-op. Use timed waits (e.g. wait(1000)) instead.
Interruptions are a safe way to signal a thread that you want something from it - stop processing, wake up and respond to something, etc.
In general, these things depend on your concrete scenarios. Java has some nice features about concurrency which can be more applicable to a situation.

Categories