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

David M. Lloyd david.lloyd at redhat.com
Fri Nov 11 12:00:09 EST 2011


Absolutely.  Spurious wakeups are an indelible part of the 
park()/unpark() contract, and in fact can make coding certain things 
possible or at least much easier.  Never, ever, ever, ever assume that 
they can't happen, no matter what you hear from anyone.

On 11/11/2011 10:50 AM, Nathan Reynolds wrote:
> 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
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


-- 
- DML


More information about the Concurrency-interest mailing list