Interrupted exception chaining

D

Daniele Futtorovic

Is there a recommended way of "chaining" interrupted exceptions?

This is to implement a method call that doesn't throw an interrupted exception, but which calls a method which can be interrupted.

public void uninterruptableWait(Object c) {
boolean done = false;
boolean interrupted = false;
synchronized (c) {
while (!done) {
try {
c.wait();
done = true;
} catch (InterrupedException ie) {
interrupted = true;
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}

If that interrupt was unexpected, and causes a stack trace, then it would be nice if it could include the details from the thrown exception.

Is there a better way to do the above?

a) When catching an InterruptedException, always, always call
Thread.currentThread().interrupt() in the catch block. Always. Unless
you know what you're doing.

b) If you want a stacktrace, just print a stacktrace. Like, in the catch
block. But note that by definition, interruptedness is a state, not an
action. The only thing a stacktrace will tell you is where in the code
that state was /checked/, not where it was /set/.
 
E

Eric Sosman

Hi,



Since he calls Thread.currentThread().interrupt() the next
wait() will throw an InterruptedException.

"The next wait()" is a re-execution of the first wait().
It is re-called *before* Thread.currentThread().interrupt(),
and will therefore *not* throw an InterruptedException until
and unless some other thread calls interrupt().
But the biggest flaw I see in the original code, is that
done=true is not called in the exception handler, so it will
not break out of the code. Actually it will inflict a new
InterruptedException by the wait() and so on.

Ah! So your diagnosis above is not about the O.P.'s code
at all, but about an undisclosed modification you have imagined.
Fine: Feel free to debug your own imagination. (Start with the
"will inflict" part, because AFAICS no such thing will happen.)
(Erics and marks code have a similar flaw, the flaw there
is that wait() is again called, so code could block)

Both markspace and I pointed out that the O.P.'s code is
fundamentally flawed. My rewrite solved the question as asked,
while preserving the original flaw; markspace's addressed it
in a slightly different way, still preserving the flaw. I think
it hardly fair to blame me and markspace for the flaw we both
carefully preserved (and pointed out).
Probably the code is only working, since wait()s are allowed
to be spurious. But if this is not happening the CPU will
burn, burn, burn, ...

This the first time I have encountered "spurious" in the
description of a *call* to wait(). It is known that a *return*
from wait() may be "spurious" in the sense that it can occur
without a notify() or notifyAll() or interrupt(), but in what
sense can the *call* be "spurious?"
 
J

Jan Burse

Daniele said:
a) When catching an InterruptedException, always, always call
Thread.currentThread().interrupt() in the catch block. Always. Unless
you know what you're doing.

No
 
J

Jan Burse

Jan said:

Mh, yes. Catch it at the right moment, outside your loop.
And yes Thread.currentThread().interrupt() isn't the worst.

And don't forget all your I/O can also be interrupted, so
you have to watch as well the following exception:

InterruptedIOException
http://docs.oracle.com/javase/1.4.2/docs/api/java/io/InterruptedIOException.html

But it usually goes unrecognized or ripples down, since
it is a subclass of IOException. Also the bytesTransferred
doesn't work well, especially if the stream is wrapped.

Bye
 
D

Daniele Futtorovic

Mh, yes. Catch it at the right moment, outside your loop.
And yes Thread.currentThread().interrupt() isn't the worst.

And don't forget all your I/O can also be interrupted, so
you have to watch as well the following exception:

InterruptedIOException
http://docs.oracle.com/javase/1.4.2/docs/api/java/io/InterruptedIOException.html


But it usually goes unrecognized or ripples down, since
it is a subclass of IOException. Also the bytesTransferred
doesn't work well, especially if the stream is wrapped.

The point, which I believe you're missing, is that when you catch the
InterruptedException, the thread's interrupted status is _cleared_.
Normally, you don't want to lose that information (to wit, that it's
been interrupted). Unless, again, you specifically know what you're
doing. But since in my experience the overwhelming majority of
developers, even the experienced ones, are unaware of this fact, I
reckon it warrants a little vehemence.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,202
Latest member
MikoOslo

Latest Threads

Top