Velocity Reviews - Computer Hardware Reviews

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

Reply
Thread Tools

Interrupted exception chaining

 
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Jan Burse schrieb:
> If it doesn't we cannot distinguish between a spurious wait (*) and
> a wait by a notify.


Corr.:
If it doesn't we cannot distinguish between a spurious wakeup (*) and
a wakeup by a notify.

This is how the notify should be done, it needs also to
use a synchronized():

public void signalDone() {
synchronized(lock) {
done=true;
lock.notifyAll();
}
}

I prefer using notifyAll() from the beginning, since the condition
that is signaled can get more and more complex over the time, and
it might be that some threads will or will not react to it, so that
notify() might pick one which will not react, and then the signal
is spurious.

Bye
 
Reply With Quote
 
 
 
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Jan Burse schrieb:
> that is signaled can get more and more complex over the time

Code evolution.
 
Reply With Quote
 
 
 
 
markspace
Guest
Posts: n/a
 
      09-25-2012
On 9/25/2012 1:47 PM, Jan Burse wrote:
> 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 */



While I agree this works in some cases, I don't think it works for the
OP. He's trying to simulate a spin lock, by extending the Lock
interface. "done" is signaled by calling unlock() on that interface.

I don't see how that can be done reliably.

public class SpinLock implements Lock {
private volatile boolean done;
private final Object lock = new Object();

public void lock() {
// ignore the "spin lock" for now
try {
synchronized( lock ) {
while( !done ) lock.wait();
}
} catch( InterruptedException ex ) {
Thread.currentThread().interrupt();
}
// how does "done" get reset?
}

public void unlock() {
synchronized( lock ) {
done = true;
lock.notify();
}
}
}

I don't see how "done" can be reliably reset. There's going to be a
race condition somewhere. Might as well use ReetrantLock, it solves
this problem.

(You can solve it too, but you're basically cutting and pasting code
from ReetrantLock at that point. Easier to just reuse code.)


 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
markspace schrieb:
>> public boolean done; /* should be set by the thread that
>> notifies the lock */

>
>
> While I agree this works in some cases,


Just replace done by the <cond> you want to anyway check.
The main point is that you cannot go, since factoring
out the programming pattern works not:


synchronized (c) {
while (!<cond>)
uninterruptableWait(c);
}


But rather simply apply the programming pattern:

try {
synchronized (c) {
while (!<cond>)
c.wait();
}
} catch( InterruptedException ex ) {
Thread.currentThread().interrupt();
}

Or if you want to scare the hell out of your clients, use:

public interface Predicate {
public boolean _true(Object c);
}

public void uninterruptableWait(Object c, Predicate p) {
try {
synchronized (c) {
while (!p._true(c))
c.wait();
}
} catch( InterruptedException ex ) {
Thread.currentThread().interrupt();
}
}

Then what you call "SpinLock", but what I would call
"OneTimeLock". Can be implemented as follows:

public void waitDone() {
uninterruptableWait(lock,new Predicate() {
return done;
});
}

Of course you can turn a "OneTimeLock" into a "ManyTimeLock",
for example. You can reset the done inside the synchronized
of the waitDone(). The synchronized will assure that when
you leave the synchronized the done=false holds, since no
other thread will interfer while inside the synchronized
and after the wait():

public void waitDone() {
try {
synchronized( lock ) {
while( !done )
lock.wait();
done=false;
}
} catch( InterruptedException ex ) {
Thread.currentThread().interrupt();
}
}

To abstract this pattern we would need:


public interface Predicate {
public boolean _true(Object c);
}

public interface Action{
public boolean perform(Object c);
}

public void uninterruptableWait(Object c, Predicate p, Action a) {
try {
synchronized (c) {
while (!p._true(c))
c.wait();
a.perform(c);
}
} catch( InterruptedException ex ) {
Thread.currentThread().interrupt();
}
}

And one can then do:

public void waitDone() {
uninterruptableWait(lock,new Predicate() {
return done;
}, new Action() {
done=false;
});
}

Eagerly avaiting JDK 7 lambdas...

Bye

 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Jan Burse schrieb:
>
> Eagerly avaiting JDK 7 lambdas...

Oops, JDK 8, 9, or whatever...
 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Jan Burse schrieb:
> public void waitDone() {
> uninterruptableWait(lock,new Predicate() {
> return done;
> }, new Action() {
> done=false;
> });
> }
>
> Eagerly avaiting JDK 7 lambdas...


You see, I didn't write it right, it is of course:


public void waitDone() {
uninterruptableWait(lock,new Predicate() {
public _true(Object c) {
return done;
}
}, new Action() {
public perform(Object c) {
done=false;
}
});
}

So since there are not yet lambdas, we have to
write the method names of the interfaces. But
JDK 8 lambdas would exactly do this for us,
fill in the blanks. Sadly I don't currently
find the blog by John Rose that explains it.

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

markspace schrieb:
> I don't see how "done" can be reliably reset. There's going to be a
> race condition somewhere. Might as well use ReetrantLock, it solves
> this problem.


Do you refer to:

Condition.awaitUninterruptibly() ?
http://docs.oracle.com/javase/1.5.0/...ruptibly%28%29

Didn't look yet at the source. What is the design?

Bye




 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
Jan Burse schrieb:
> Hi,
>
> markspace schrieb:
>> I don't see how "done" can be reliably reset. There's going to be a
>> race condition somewhere. Might as well use ReetrantLock, it solves
>> this problem.

>
> Do you refer to:
>
> Condition.awaitUninterruptibly() ?
> http://docs.oracle.com/javase/1.5.0/...ruptibly%28%29
>
>
> Didn't look yet at the source. What is the design?
>
> Bye


I guess if we were to allow to introduce a data structure
Condition or so, we could also do the same. Provide an
uninterruptableWait on this Condition. So we would again
divert from the original:

public static void uninterruptableWait(Object c);

And either have:

public static void uninterruptableWait(Condition c);

Or:

public class Condition;
public void uninterruptableWait();

Simplest datastructure would be:

public class Condition {
public Object lock = new Object();
public boolean done;
}

Bye



 
Reply With Quote
 
Jan Burse
Guest
Posts: n/a
 
      09-25-2012
But the programming pattern for awaitUninterruptibly() would
be different from uninterruptableWait(). Since the spec says
that spurious wakeups are still posible. So I guess something
along:

while (!(flag=Thread.interrupted()) && !<cond>)
awaitUninterruptibly();
if (!flag)
<action>
} else {
Thread.currentThread().interrupt();
}

Ugly


Jan Burse schrieb:
> Hi,
>
> markspace schrieb:
>> I don't see how "done" can be reliably reset. There's going to be a
>> race condition somewhere. Might as well use ReetrantLock, it solves
>> this problem.

>
> Do you refer to:
>
> Condition.awaitUninterruptibly() ?
> http://docs.oracle.com/javase/1.5.0/...ruptibly%28%29
>
>
> Didn't look yet at the source. What is the design?
>
> Bye
>
>
>
>


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

> Ugly
>



Truly! And it only took you eight replies, mostly to your own posts, to
arrive at that idea. I think I mentioned ReetrantLock up thread? And
you should look at the source of that class, it's very interesting.



 
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
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57