Re: The code example in onSpinWait() Javadoc
Francesco Nigro via Concurrency-interest <[email protected]>
| Newsgroups | gmane.comp.java.jsr.166-concurrency |
|---|---|
| Message-ID | <CAKxGtTWAGkedRV6gMYan-rfr57rx9AVErsJsSC_B-WEorL1LEw@mail.gmail.com> |
Gil Tene* Android typo error Il gio 14 nov 2019, 23:28 Francesco Nigro <[email protected]> ha scritto: > I would like to hear the opinion of Gil Gene about it too: AFAIK he was > the one (or one of many?) that has proposed it to be included in > http://openjdk.java.net/jeps/285 > > Il gio 14 nov 2019, 23:22 Francesco Nigro <[email protected]> ha > scritto: > >> 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 <[email protected]> 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, < >>> [email protected]> 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 < >>>> [email protected]> 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 <[email protected]> >>>>> 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 >>>> [email protected] >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>>> >>> _______________________________________________ Concurrency-interest mailing list [email protected] http://cs.oswego.edu/mailman/listinfo/concurrency-interest