<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=EN-US link=blue vlink="#954F72"><div class=WordSection1><p class=MsoNormal>I don’t see how this is more racy than the original code…</p><p class=MsoNormal>As soon as you call compareAndSet() the value might have changed.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I have a place in my code, where this make a significant performance difference on x86.</p><p class=MsoNormal>Volatile read is just a read and a single compare with predicted branch returns most of the time.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Sent from <a href="https://go.microsoft.com/fwlink/?LinkId=550986">Mail</a> for Windows 10</p><p class=MsoNormal><o:p> </o:p></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal style='border:none;padding:0in'><b>From: </b><a href="mailto:davidcholmes@aapt.net.au">David Holmes</a><br><b>Sent: </b>Tuesday, May 23, 2017 8:16 PM<br><b>To: </b><a href="mailto:openjdk@duigou.org">'Mike Duigou'</a>; <a href="mailto:concurrency-interest@cs.oswego.edu">'Concurrency Interest'</a><br><b>Subject: </b>Re: [concurrency-interest] AtomicReference.updateAndGet() mandatoryupdating</p></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Hi Mike,</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>What you suggest is too racy. As soon as you call get() the value may change such that you do want to update it - even if back to what it was previously. Only by doing the CAS can you be sure that nothing changed and you truly updated things in the manner expected.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Cheers,</p><p class=MsoNormal>David</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>> -----Original Message-----</p><p class=MsoNormal>> From: Concurrency-interest [mailto:concurrency-interest-bounces@cs.oswego.edu] On Behalf Of Mike Duigou</p><p class=MsoNormal>> Sent: Wednesday, May 24, 2017 9:59 AM</p><p class=MsoNormal>> To: Concurrency Interest <concurrency-interest@cs.oswego.edu></p><p class=MsoNormal>> Subject: [concurrency-interest] AtomicReference.updateAndGet() mandatory updating</p><p class=MsoNormal>> </p><p class=MsoNormal>> Currently the AtomicReference updateAndGet implementation will unconditionally perform a compareAndSet using the result of the</p><p class=MsoNormal>> update function.</p><p class=MsoNormal>> </p><p class=MsoNormal>> public final V updateAndGet(UnaryOperator<V> updateFunction) {</p><p class=MsoNormal>>    V prev, next;</p><p class=MsoNormal>>    do {</p><p class=MsoNormal>>      prev = get();</p><p class=MsoNormal>>      next = updateFunction.apply(prev);</p><p class=MsoNormal>>    } while (!compareAndSet(prev, next));</p><p class=MsoNormal>>    return next;</p><p class=MsoNormal>> }</p><p class=MsoNormal>> </p><p class=MsoNormal>> I find that I write a lot of update functions which only occasionally change the value. For these cases I wonder if it would be reasonable</p><p class=MsoNormal>> to skip the update if the value of next is unchanged from previous. A proposed alternative (there are analogues for Integer and Long).</p><p class=MsoNormal>> </p><p class=MsoNormal>> public final V updateAndGet(UnaryOperator<V> updateFunction) {</p><p class=MsoNormal>>    V prev, next;</p><p class=MsoNormal>>    do {</p><p class=MsoNormal>>      prev = get();</p><p class=MsoNormal>>      next = updateFunction.apply(prev);</p><p class=MsoNormal>>    } while (prev != next && !compareAndSet(prev, next));</p><p class=MsoNormal>>    return next;</p><p class=MsoNormal>> }</p><p class=MsoNormal>> </p><p class=MsoNormal>> The cases to consider are:</p><p class=MsoNormal>> </p><p class=MsoNormal>> 1. prev == value == next :: Nothing changed.</p><p class=MsoNormal>> </p><p class=MsoNormal>> In this case omitting the compareAndSet is a useful optimization. No difference for external observer.</p><p class=MsoNormal>> </p><p class=MsoNormal>> </p><p class=MsoNormal>> 2. (prev == value) != next :: Only next changed</p><p class=MsoNormal>> </p><p class=MsoNormal>> In this case the compareAndSet would be performed and succeed as prev ==</p><p class=MsoNormal>> value. No difference for external observer.</p><p class=MsoNormal>> </p><p class=MsoNormal>> </p><p class=MsoNormal>> 3. prev != value != next :: Both next and value changed. A concurrent</p><p class=MsoNormal>> modification.</p><p class=MsoNormal>> </p><p class=MsoNormal>> In this case the compareAndSet would be performed and will fail as prev</p><p class=MsoNormal>> != val. No difference for external observer.</p><p class=MsoNormal>> </p><p class=MsoNormal>> </p><p class=MsoNormal>> 4. (prev == next) != value :: Only value changed. A concurrent</p><p class=MsoNormal>> modification.</p><p class=MsoNormal>> </p><p class=MsoNormal>> In the original implementation the compareAndSet would fail resulting in</p><p class=MsoNormal>> another update attempt. In proposed implementation the compareAndSet</p><p class=MsoNormal>> would not be attempted and the value returned would be unchanged. The</p><p class=MsoNormal>> concurrent modification of value is ignored. Surely this is wrong! It</p><p class=MsoNormal>> appears wrong because some other thread beat us and updated the value.</p><p class=MsoNormal>> The question is whether our thread could tell the difference between the</p><p class=MsoNormal>> call it made to updateAndGet completing first and a concurrent update</p><p class=MsoNormal>> being ignored. Other than via side-effects in updateFunction it does not</p><p class=MsoNormal>> appear that it could. To an external observer this case is</p><p class=MsoNormal>> indistinguishable from the first where there was no concurrent update.</p><p class=MsoNormal>> Even if there is a concurrent update it will appear to callers that</p><p class=MsoNormal>> non-mutating updates always completed first.</p><p class=MsoNormal>> </p><p class=MsoNormal>> Useful? Wrongheaded?</p><p class=MsoNormal>> </p><p class=MsoNormal>> Mike</p><p class=MsoNormal>> _______________________________________________</p><p class=MsoNormal>> Concurrency-interest mailing list</p><p class=MsoNormal>> Concurrency-interest@cs.oswego.edu</p><p class=MsoNormal>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>_______________________________________________</p><p class=MsoNormal>Concurrency-interest mailing list</p><p class=MsoNormal>Concurrency-interest@cs.oswego.edu</p><p class=MsoNormal>http://cs.oswego.edu/mailman/listinfo/concurrency-interest</p><p class=MsoNormal><o:p> </o:p></p></div></body></html>