Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Interrupted exception chaining

Reply
Thread Tools

Interrupted exception chaining

 
 
raphfrk@gmail.com
Guest
Posts: n/a
 
      09-25-2012
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?
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      09-25-2012
On 9/25/2012 6:25 AM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> 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) {


(Aside: This could probably be a `static' method.)

> boolean done = false;
> boolean interrupted = false;
> synchronized (c) {
> while (!done) {
> try {
> c.wait();
> done = true;
> } catch (InterrupedException ie) {


(Aside: `InterrupttttttttttttttttttttedException'.)

> 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?


It seems you're trying to have things both ways: You "expect"
the interrupt by catching it, but then want to consider it as
"unexpected" anyhow. Also, you want to inform your caller but
have chosen not to throw an informative exception.

Since an exception is just an object, I suppose you *could*
have the method return it, or return `null' if there was none:

/**
* Waits for notify() or notifyAll() on an object, in
* spite of interruptions.
* @param c The object to wait for.
* @return {@code null} if no interrupts occurred while
* waiting, or one of the {@code InterruptedException}s
* if one or more were thrown.
*/
public static InterruptedException
uninterruptableWait(Object c) {
InterruptedException ex = null;
for (; {
try {
c.wait();
return ex;
} catch (InterruptedException ie) {
ex = ie;
}
}
}

This looks vile to me, though. I think your difficulty is
self-inflicted, and should be solved by rethinking your design.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
 
 
 
markspace
Guest
Posts: n/a
 
      09-25-2012
On 9/25/2012 3:25 AM, (E-Mail Removed) wrote:
> Is there a recommended way of "chaining" interrupted exceptions?



I mostly agree with Eric. You shouldn't suppress interrupts unless you
must. If for example you are implementing a Runnable, you can't throw
InterruptedException but must deal with it somehow. Then catching an
interrupted exception is reasonable.

In this case however it's 100% your code and you could throw
InterruptedException. That would defeat the purpose of the code you
show, of course, but then that is also our point: what you are doing is
rather questionable.

There's no standard pattern for this because it's not done. I'd say the
closest we have to to use a finally block to make certain the interrupt
flag is restored.


/** A questionable method: wait without throwing InterruptedException. */
public void uninterruptableWait(Object c) {
boolean interrupted = false;
try {
synchronized(c) {
for(; {
try {
c.wait();
return;
} catch(InterruptedExcpetion ex ) {
interrupted = true;
}
}
}
} finally {
if(interrupted == true ) 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.



If you really need the details of the exception but can't throw from
your local use site, I'd say wrapping the exception in a
RuntimeExcpetion and throwing that is best. (Exception don't ever
throwing RuntimeException; subclass it and throw your specific exception.)


 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      09-25-2012
On 9/25/12 3:25 AM, (E-Mail Removed) wrote:
> 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?


To take a pattern from Spring Binding (which may have taken it from
elsewhere), you can keep a list of the caught exceptions, and then at
the end of your method if that list is not empty, throw a new exception
which contains the list.

BTW, the stack-trace will only be on the c.wait() line, since that is
where the interrupted exception will be thrown. This does not help you
know who interrupted you unexpectedly.

Do you really have a use-case for uninterruptableWait? Perhaps you
should instead have a different approach to interrupting that thread.
An interrupt is often a result of a user-action, and ignoring it will
make users mad. It may also be the case that the interrupt was caused
because something else failed, and waiting no longer is useful.

I'd be curious to read your use case. I've written similar code in the
past, and have since realized it was misguided.

Good luck,
Daniel.
 
Reply With Quote
 
Ivan Ryan
Guest
Posts: n/a
 
      09-25-2012
On Sep 25, 4:33*pm, markspace <-@.> wrote:
> On 9/25/2012 3:25 AM, (E-Mail Removed) wrote:
>
> > Is there a recommended way of "chaining" interrupted exceptions?

>
> I mostly agree with Eric. *You shouldn't suppress interrupts unless you
> must.


Well, the idea is to be able to have a method where the caller doesn't
have to worry about handling interrupts.

> If you really need the details of the exception but can't throw from
> your local use site, I'd say wrapping the exception in a
> RuntimeExcpetion and throwing that is best. *(Exception don't ever
> throwing RuntimeException; subclass it and throw your specific exception.)


It was to implement an interface.
https://github.com/SpoutDev/SpoutAPI.../SpinLock.java
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      09-25-2012
On 9/25/2012 12:28 PM, Ivan Ryan wrote:
> On Sep 25, 4:33 pm, markspace <-@.> wrote:
>> On 9/25/2012 3:25 AM, (E-Mail Removed) wrote:
>>
>>> Is there a recommended way of "chaining" interrupted exceptions?

>>
>> I mostly agree with Eric. You shouldn't suppress interrupts unless you
>> must.

>
> Well, the idea is to be able to have a method where the caller doesn't
> have to worry about handling interrupts.


Fine: The called method handles its own interrupts, and
that's that. But then, the O.P. wants the information about
the interrupt to propagate back to the caller -- the very same
caller that "doesn't have to worry about handling interrupts!"

"Pick a card, any card, don't show it to me. Okay, what
card is it?"

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
markspace
Guest
Posts: n/a
 
      09-25-2012
On 9/25/2012 9:28 AM, Ivan Ryan wrote:

> It was to implement an interface.
> https://github.com/SpoutDev/SpoutAPI.../SpinLock.java



This looks 100% bogus to me. First, the JVM will insert spin-locks
where needed in your code automatically. No need to try to build your
own. The first rule of programming is "Don't re-invent the wheel."
(The 0th rule is "Get a deposit with all contracts.")

Second this is exactly the sort of situation where hiding an
InterrruptedException will get you into trouble. Better to just
re-throw and let the calling code deal with the exception (if desired).

But even better to just delete this class and use
java.util.concurrent.locks.ReetrantLock or something similar from the
Java API.

Plus, existing locks are more efficient that you might guess. I don't
think an AtomicBoolean is going to beat them. Look into
AbstractQueuedSynchronizer or LockSupport if you really must implement
your own subclass of Lock.

<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/locks/ReentrantLock.java#111>



 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Hi,

Daniel Pitts schrieb:
> Do you really have a use-case for uninterruptableWait? Perhaps you
> should instead have a different approach to interrupting that thread. An
> interrupt is often a result of a user-action, and ignoring it will make
> users mad. It may also be the case that the interrupt was caused
> because something else failed, and waiting no longer is useful.


Since he calls Thread.currentThread().interrupt() the next
wait() will throw an InterruptedException. So it is not
really ignored. It will be only ignored if all of the code
uses uninterruptableWait(), and nowhere Thread.interrupted()
is queried.

(E-Mail Removed) wrote:
> Is there a better way to do the above?


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.

(Erics and marks code have a similar flaw, the flaw there
is that wait() is again called, so code could block)

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, ...

Bye

 
Reply With Quote
 
markspace
Guest
Posts: n/a
 
      09-25-2012
On 9/25/2012 1:26 PM, Jan Burse wrote:

>
> (Erics and marks code have a similar flaw, the flaw there
> is that wait() is again called, so code could block)



That's actually a fair point. "Doesn't throw" isn't the same as
"ignore." However, ReentrantLock is probably still better than the
following code.


/** A questionable method: wait without throwing InterruptedException. */
public void uninterruptableWait(Object c) {
boolean interrupted = false;
try {
synchronized(c) {
try {
c.wait();
return;
} catch(InterruptedExcpetion ex ) {
interrupted = true;
}
}
} finally {
if(interrupted == true ) Thread.currentThread().interrupt();
}
}

 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Hi,

Anyway the code that will notify c should also set some state.
If it doesn't we cannot distinguish between a spurious wait (*) and
a wait by a notify. So code must use a loop, and to not confuse
the done flag and loop breaking, we can just shift the try/catch
outside of the loop, and even outside of the synchronized to
minimize the monitor region:

public boolean done; /* should be set by the thread that
notifies the lock */
public Object lock = new Object();

public void uninterruptedWait() {
try {
synchronized(lock) {
while (!done)
lock.wait();
}
} catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}


(*)
The doc mentions it explicitly:

As in the one argument version, interrupts and *spurious wakeups* are
possible, and this method should always be used in a *loop*:
http://docs.oracle.com/javase/7/docs...tml#wait%28%29

Bye

markspace schrieb:
> That's actually a fair point. "Doesn't throw" isn't the same as
> "ignore." However, ReentrantLock is probably still better than the
> following code.
>
>
> /** A questionable method: wait without throwing InterruptedException. */
> public void uninterruptableWait(Object c) {
> boolean interrupted = false;
> try {
> synchronized(c) {
> try {
> c.wait();
> return;
> } catch(InterruptedExcpetion ex ) {
> interrupted = true;
> }
> }
> } finally {
> if(interrupted == true ) Thread.currentThread().interrupt();
> }
> }
>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: backporting PEP 3134 "Exception Chaining and Embedded Tracebacks"to Python 2.7 Demian Brecht Python 0 02-19-2013 08:56 PM
backporting PEP 3134 "Exception Chaining and Embedded Tracebacks" toPython 2.7 Piotr Dobrogost Python 0 02-19-2013 08:54 PM
Does Ruby support exception wrapping (exception chaining)? Hartin, Brian Ruby 15 02-23-2011 07:02 AM
"Interrupted function call" exception while relogging :( Sylwia Python 2 01-08-2004 03:32 PM
"Interrupted function call" exception in Python service while relogging Nazgul Python 0 01-08-2004 09:43 AM



Advertisments