[concurrency-interest] Propagation of signals tonon-interrupted thread

Nathan Reynolds nathan.reynolds at oracle.com
Fri Nov 11 11:50:02 EST 2011


Does Solaris/SPARC or some other platform still cause spurious wakeups?  
Or is this email chain saying that has been fixed?

Spurious wakeups should always be considered possible even if the 
hardware and JVM don't allow it.  LockSupport.unpark() can be called by 
any thread in any piece of code.  It has a globally accessible flag.  
One piece of code could call unpark() and cause what seems to be a 
"spurious" wakeup in another piece of code.

For example, let's say some buggy code allows for two threads (A & B) to 
call LockSupport.unpark() on the same thread (C).  Thread A calls 
unpark().  Thread C wakes up exits that piece of code and then goes into 
another piece of code.  Thread C then calls LockSupport.park().  Thread 
B gets some CPU time and calls LockSupport.unpark() on Thread C.  Thread 
C now wakes up and thinks it has been signaled correctly.  This problem 
is really tough to debug because the two pieces of code are completely 
unrelated except via LockSupport.

Coding for spurious wakeups (i.e. rechecking the condition) is always a 
good thing.  Sure the piece of code you are looking at could be 
perfect.  But, some other piece of code which you have never seen could 
be doing things in a way that breaks your code.

Nathan Reynolds 
<http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> | 
Consulting Member of Technical Staff | 602.333.9091
Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology

On 11/11/2011 8:36 AM, Tim Peierls wrote:
> This just bit me. (I never really followed the discussions that 
> resulted in that documentation strategy.) I suggested some code for 
> someone that I claimed was not ready to use because it didn't handle 
> spurious wakeups. I now think in fact it /was/ ready to use. Better 
> safe than sorry, of course, but it would have been nicer to read that 
> await was not prone to spurious wakeups along with a reminder that in 
> many cases await should be called in a loop to check the condition.
>
> --tim
>
> On Thu, Nov 10, 2011 at 5:56 PM, David Holmes 
> <davidcholmes at aapt.net.au <mailto:davidcholmes at aapt.net.au>> wrote:
>
>     Martin,
>     As discussed in the past the reason for not
>     documenting/guaranteeing "no spurious wakeups" is that it would
>     encourage people to use await() in an if-statement rather than a
>     loop, which would often be incorrect even without spurious
>     wakeups. It is a safer multi-threaded world if programmers believe
>     that spurious wakeups are lying in wait (pun intended) and so are
>     always accounted for - this will instil safe programming practice
>     across all the main threading systems.
>     Cheers,
>     David
>
>         -----Original Message-----
>         *From:* concurrency-interest-bounces at cs.oswego.edu
>         <mailto:concurrency-interest-bounces at cs.oswego.edu>
>         [mailto:concurrency-interest-bounces at cs.oswego.edu
>         <mailto:concurrency-interest-bounces at cs.oswego.edu>]*On Behalf
>         Of *Martin Buchholz
>         *Sent:* Friday, 11 November 2011 12:07 AM
>         *To:* Dr Heinz M. Kabutz
>         *Cc:* concurrency-interest at cs.oswego.edu
>         <mailto:concurrency-interest at cs.oswego.edu>
>         *Subject:* Re: [concurrency-interest] Propagation of signals
>         tonon-interrupted thread
>
>         These classes are designed to work with JDK6 as well as JDK7.
>
>         AbstractQueuedSynchronizer has been written so that interrupts
>         can never cause signals to be lost.  If this were not the
>         case, there would be many more places than just
>         in ArrayBlockingQueue where special handling of interrupts
>         would be required (and getting concurrent classes right is
>         already hard enough).  Implementation of ABQ has merely been
>         simplified to rely on AQS's de-facto guarantee.
>
>         This ought to be better documented.
>
>         I would like to see the classes in j.u.c.locks document more
>         guarantees than they currently do.
>         For example, I'd like to see this guarantee:
>
>         diff -u -r1.96 ReentrantLock.java
>         --- main/java/util/concurrent/locks/ReentrantLock.java9 Jun
>         2011 07:48:44 -00001.96
>         +++ main/java/util/concurrent/locks/ReentrantLock.java10 Nov
>         2011 14:00:08 -0000
>         @@ -467,6 +467,9 @@
>               * but for <em>fair</em> locks favors those threads that
>         have been
>               * waiting the longest.
>               *
>         +     * <li>None of the condition {@linkplain
>         Condition#await() waiting}
>         +     * methods ever return due to a "<em>spurious
>         wakeup</em>".
>         +     *
>               * </ul>
>               *
>               * @return the Condition object
>
>         Martin
>
>         On Thu, Nov 10, 2011 at 05:15, Dr Heinz M. Kabutz
>         <heinz at javaspecialists.eu <mailto:heinz at javaspecialists.eu>>
>         wrote:
>
>             In Java 6, the ArrayBlockingQueue used this construct for
>             the take() method:
>
>               public E take() throws InterruptedException {
>                   final ReentrantLock lock = this.lock;
>                   lock.lockInterruptibly();
>                   try {
>                       try {
>                           while (count == 0)
>                               notEmpty.await();
>                       } catch (InterruptedException ie) {
>                           notEmpty.signal(); // propagate to
>             non-interrupted thread
>                           throw ie;
>                       }
>                       E x = extract();
>                       return x;
>                   } finally {
>                       lock.unlock();
>                   }
>               }
>
>             In other words, it would /always/ send a signal on
>             interrupt, even if it had not received one.
>
>             In Java 7, this was taken away, so we now have:
>
>               public E take() throws InterruptedException {
>                   final ReentrantLock lock = this.lock;
>                   lock.lockInterruptibly();
>                   try {
>                       while (count == 0)
>                           notEmpty.await();
>                       return extract();
>                   } finally {
>                       lock.unlock();
>                   }
>               }
>
>             However, I could not find substantial differences between
>             the await() methods of Java 6 and 7.  Does this mean that
>             propagating of the signal was not necessary in Java 6
>             either?  According to Doug Lea's book section 3.2.4.2, it
>             is necessary with wait/notify to propagate the signal if
>             you get interrupted.  However, it looks like
>             Condition.await() is coded to cater for this eventuality
>             anyway.
>
>             Regards
>
>             Heinz
>             -- 
>             Dr Heinz M. Kabutz (PhD CompSci)
>             Author of "The Java(tm) Specialists' Newsletter"
>             Sun Java Champion
>             IEEE Certified Software Development Professional
>             http://www.javaspecialists.eu
>             Tel: +30 69 72 850 460 <tel:%2B30%2069%2072%20850%20460>
>             Skype: kabutz
>             _______________________________________________
>             Concurrency-interest mailing list
>             Concurrency-interest at cs.oswego.edu
>             <mailto:Concurrency-interest at cs.oswego.edu>
>             http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>     _______________________________________________
>     Concurrency-interest mailing list
>     Concurrency-interest at cs.oswego.edu
>     <mailto:Concurrency-interest at cs.oswego.edu>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111111/a72f3249/attachment.html>


More information about the Concurrency-interest mailing list