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

Tim Peierls tim at peierls.net
Fri Nov 11 10:36:27 EST 2011


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>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]*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
> *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.java 9 Jun 2011
> 07:48:44 -0000 1.96
> +++ main/java/util/concurrent/locks/ReentrantLock.java 10 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> 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
>> Skype: kabutz
>> ______________________________**_________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.**oswego.edu <Concurrency-interest at cs.oswego.edu>
>> http://cs.oswego.edu/mailman/**listinfo/concurrency-interest<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/1e7e385b/attachment-0001.html>


More information about the Concurrency-interest mailing list