[concurrency-interest] The code example in onSpinWait() Javadoc

Francesco Nigro nigro.fra at gmail.com
Thu Nov 14 17:22:21 EST 2019


Beside being more complex?
Not much I admit :)
But IMO awaiting with no algorithmical indication of the duration of the
wait (like in the javadoc) and awaiting for a finite amount of "time" a
condition that will be true at some point, is a better example where to
apply onSpinWait, although is not technically incorrect to use it for
"blind" spin loop as well.
Maybe is just a subtle difference, but I won't encourage users to blindly
spin loop on conditions and just use onSpinWait to save the day.. probably
I'm worried too much for something very simple and unavoidable; as @roman
has suggested, probably no example is better then one that is a superclass
of all the possible best cases.


Il gio 14 nov 2019, 22:51 Alex Otenko <oleksandr.otenko at gmail.com> ha
scritto:

> What's the difference between this example and what's in javadocs?
>
> Alex
>
> On Thu, 14 Nov 2019, 16:29 Francesco Nigro via Concurrency-interest, <
> concurrency-interest at cs.oswego.edu> wrote:
>
>> Totally right, sorry again (writing by phone is a terrible idea :( ):
>> yes , poll should  use  "o = this.obj".
>>
>> > Can we get rid of "done"?  Since offerOnce() does not allow null, then
>> having the done flag does not seem to help anything.
>> Absolutely yes: I've prepared this as a "simplified" (and wrong due to
>> the hurry, sorry for that) version of what we do on many queues in JCtools,
>> that's why it contains some unnecessary bits as you've rightly pointed
>> out.
>> Code that is spin awaiting on a condition, sure that it will happen at
>> some point in the future, is something that could help to understand the
>> rare cases
>> where using onSpinWait could be beneficial IMO.
>>
>>
>>
>> Il giorno gio 14 nov 2019 alle ore 17:18 Nathan and Ila Reynolds <
>> nathanila at gmail.com> ha scritto:
>>
>>> In poll(), should "this.obj = o" be "o = this.obj"?  Without this
>>> change, it seems poll() could spin forever.
>>>
>>> Should "poll" be renamed to "take" since the method could block until a
>>> value is available?
>>>
>>> Can we get rid of "done"?  Since offerOnce() does not allow null, then
>>> having the done flag does not seem to help anything.
>>>
>>> Is the compiler and execution engine in my head misinterpreting and
>>> mis-executing the code?
>>>
>>> Here is the code with my suggested changes.
>>>    volatile E obj = null;
>>>
>>>    public void offerOnce(E o) {
>>>       Objects.checkNonNull(o);
>>>       this.obj = o;
>>>    }
>>>
>>>   public boolean isDone() {
>>>        return obj != null;
>>>   }
>>>
>>>    public E take() {
>>>       E o;
>>>
>>>       while (true) {
>>>          o = obj;
>>>
>>>          if (o != null)
>>>             return o;
>>>
>>>          java.lang.Thread.onSpinWait();
>>>       }
>>>    }
>>>
>>> -Nathan
>>>
>>> On 11/14/2019 8:54 AM, Francesco Nigro wrote:
>>>
>>> Sorry I've written on the email text, I forgot an important part, let me
>>> write it properly:
>>>
>>>    volatile E obj = null;
>>>    volatile boolean done = false;
>>>
>>>    public void offerOnce(E o) {
>>>       Objects.checkNonNull(o);
>>>       this.done = true;
>>>       this.obj = o;
>>>    }
>>>
>>>   public boolean isDone() {
>>>        return done;
>>>   }
>>>
>>>    public E poll() {
>>>       E o = this.obj;
>>>       if (o == null && !this.done) {
>>>          return null;
>>>       }
>>>       //o will be !null at some point
>>>       do {
>>>          if (o != null)
>>>             return o;
>>>          java.lang.Thread.onSpinWait();
>>>          this.obj = o;
>>>       } while(true);
>>>    }
>>>
>>> Similarly to the queue API: poll should return null iff !done, but offer
>>> update first done and then this.obj:
>>> poll need to read obj, but has to stay consistent to the ordering, so at
>>> some point, obj will be visible if done == true.
>>> On JCtools we have some queues with a similar behaviour (producer
>>> sequence is advanced before writing the actual element in the queue)
>>> and we need to spin wait the element apprearence to stay consistent with
>>> the isEmpty behaviour: that's a good use case for onSpinWait (when it works
>>> :P).
>>>
>>>
>>>
>>> Il giorno gio 14 nov 2019 alle ore 16:43 Andrew Haley <aph at redhat.com>
>>> ha scritto:
>>>
>>>> On 11/14/19 3:31 PM, Francesco Nigro via Concurrency-interest wrote:
>>>> >     E o = this.obj;
>>>> >     if (o == null && !done) {
>>>> >         return null;
>>>> >      }
>>>> >      //o will be !null at some point
>>>> >      do {
>>>> >          if (o != null)
>>>> >             return o;
>>>> >          java.lang.Thread.onSpinWait();
>>>> >      } while(true);
>>>> > }
>>>> >
>>>> > In case like this is more appropriate, maybe, but much less intuitive
>>>> > probably.
>>>>
>>>> Umm, what? o is a local. This loop spins forever.
>>>>
>>>> --
>>>> Andrew Haley  (he/him)
>>>> Java Platform Lead Engineer
>>>> Red Hat UK Ltd. <https://www.redhat.com>
>>>> https://keybase.io/andrewhaley
>>>> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
>>>>
>>>> _______________________________________________
>> 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/20191114/ccf2690c/attachment-0001.html>


More information about the Concurrency-interest mailing list