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

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.

Related

Java: Does this pause the thread correctly?

I am curious whether it is possible to pause a thread t in Java and allow another thread to resume it later, by having t run the following pause code:
while(true) {
try {
synchronized(t) {
t.wait();
}
} catch(InterruptedException e) {
break;
}
}
And then resuming the thread t by calling .interrupt() on it. However, I have read about spurious wake-ups, and so I wondered whether my code can fail, in the sense of exiting the while-loop despite no other thread calling .interrupt() on it. While this answer and this answer state that there are no spurious interrupts, and hence my code will never fail, the Java docs does not seem to address this. My question probably boils down to whether InterruptedException is ever thrown without the thread being interrupted by .interrupt(). Is there any official source or documentation that confirms this?
Summary
So, although technically this works, there are numerous reasons why this should not be done. Oracle's documentation states that interruption should only be utilized for cancellations. But if you were to do this, it will clear the interrupt status and the previously waiting thread will receive an InterruptedException.
Alternative
Lets step through a brief, simplified example.
Object obj = new Object;
synchronized (obj) {
while(condition) {
obj.wait();
}
}
A thread here will obtain the monitor.
The thread will begin to wait via wait(), and release the monitor. Always utilize wait() inside a conditional because threads are subject to get spurious wake-ups from wait(). At this point, you have achieved forcing a thread to wait.
Lets investigate how we go about returning the thread to work.
synchronized(obj) {
obj.notify();
}
The notify() will wake up the first waiting thread on the monitor. Now, if you want all waiting threads to wake up, utilize notifyAll() instead. This is the intended purpose and functionality of wait()/notify() and thus should be utilized over wait()/interrupt(). For an additional example, see this article.

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.

How can I resume a thread which is waiting for a resource?

How can I interrupt/resume a resource waiting thread back to other works? Say, My thread is waiting for response from a resource where the resource hanged or not in the state of response. How can I resume back that thread to do other works?
Can other thread send a exception to the waiting thread, so that with an exception, it can come back to it's other work?
UPDATE :
I have tried it in the following way, but no use.
I have timeout Thread, which will check whether default timeout has occurred to that particular Transaction on which the first thread wait, and if so, fire interrupt() call on the first thread.
The answer depends on many factors.
The "right" way to interrupt a thread is to use the thread.interrupt() method. This requires the thread's code to be cooperative; it should be aware of the interruption, either by handling the InterruptedException thrown by interruptible operations (such as wait or sleep), or by checking the interrupted flag of the current thread regularly.
Then, the code should decide what consequences the interruption should have. Usually, you would like a thread to terminate gracefully in case of interruption.
Instead of using interruption, I would check whether your blocking operation has a built in timeout mechanism. If it's blocked on obj.wait() for example, then you could use obj.wait(timeout) instead.
yes, you can interrupt the thread. using the Thread.interrupt mechanism, google it.

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.

Using Object.wait(millisec) to simulate sleep

Here's a snippet of code that I saw in some code I'm maintaining.
Object lock = new Object();
synchronized( lock )
{
try
{
lock.wait( 50000 );
Thread.sleep( 3000 );
}
catch(Exception ex)
{
}
}
The developer wants to suspend the current thread for some amount of time and is using Object#wait as the mechanism. Obviously it is bad form to use the wait/notify protocol for this reason; however, is there any major difference between calling wait(millisec) and a Thread.sleep ?
Aside from having to get a monitor before waiting() there's no major difference anymore so long as no one external is going to be .notify()ing.
In ancient Java code you'd see people using wait() instead of Thread.sleep() because Thread.sleep() would freeze the whole application on systems without preemptive multitasking (I'm looking at you OS9). Technically wait() also let's you use nano-resolution waits, but in practice they're seldom that accurate.
Note that there is one key difference in using Object.wait() and Thread.sleep() inside a synchronization block: Thread.sleep() does not release the locked monitor, so no-one else can become the owner of the monitor.
In addition, Object.wait() does not guarantee that the delay indicated will be obeyed strictly. First of all, after the delay passes, the thread may still be waiting for another thread that has become the monitor owner in the meantime; and it may compete with other threads waiting to grab the monitor.
Second, the mythical spurious wake-up, as it is described in the Java 6 API javadoc:
A thread can also wake up without
being notified, interrupted, or timing
out, a so-called spurious wakeup.
Unlikely as it is, every piece of code using Object.wait() should take it into consideration.
You say it's "obviously" bad form to use wait/notify for this, but I don't see anything wrong with it. Admittedly following it up with a sleep call is very odd (and swallowing exceptions is bad), but I've definitely used Object.wait as a "breakable sleep" before now.
Imagine you've got a thread polling a resource every minute, but you want to be woken if something's happened (e.g. the resource location has changed, or the timer frequency has changed, or the program wants to quit in a graceful manner). Using wait/notify works extremely well for that - it's definitely cleaner than calling interrupt on the thread from elsewhere, as it doesn't matter if the notify occurs while you're actually processing instead of waiting.

Categories