Re: Are there real use cases with the Java access modes?
Alex Otenko via Concurrency-interest <[email protected]> Thu, 22 Jul 2021 22:18:13 +0100
| Newsgroups | gmane.comp.java.jsr.166-concurrency |
|---|---|
| Message-ID | <CANkgWKirR3Fsq+xe6gMNSNL-pGKYy05vqjUAGQeWvd2C80FUCg@mail.gmail.com> |
--===============8527686665693390798== Content-Type: multipart/alternative; boundary="000000000000d5cdd005c7bcd34b" --000000000000d5cdd005c7bcd34b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable :) concurrency libraries create a sense of security. But in the end you have to tackle ordering of events, possible interleavings, lifetimes and ownership of things become unclear, who owns errors, and how to get them to the correct place in the right order. To say nothing of expression problem: loops are replaced with chains of events, and become indistinguishable from recursion. So you get rid of a lot of support the language provides for you, all for the security through obscurity. In other words, race conditions happen even in single-threaded languages like javascript or python. Alex On Thu, 22 Jul 2021, 20:15 Joe Bowbeer, <[email protected]> wrote: > In my 20+ years of reviewing Java code, my best indicator (red flag) for > the presence of bugs has been the existence of synchronized methods and/o= r > volatile fields. > > Programming concurrency at this low level (in Java) is for experts only; > whenever mere mortals try it, I can almost guarantee that I will find a b= ug. > > The only hope for beginners is to leverage single-threaded subsystems and > higher-level concurrency patterns. > > In summary, making volatile the default would make it harder for me to > find bugs =F0=9F=98=80 > > On Thu, Jul 22, 2021 at 7:40 AM Nathan Reynolds via Concurrency-interest = < > [email protected]> wrote: > >> JIT has to decide if the loop condition can be hoisted. JIT halts the >> hoisting optimization even on the world "full of nontrivial things"... a= nd >> if not the JIT team gets a bug to fix. Hence, I suspect JIT is >> conservative on how deep it tries to examine to figure out if the condit= ion >> can be hoisted. I suspect that when JIT does not know what the destinat= ion >> is (e.g. Runnable.run()), then it halts. >> >> So, the PMD rule needs to be at least as good as JIT at determining if >> the variable can be hoisted. This will prevent unintentional infinite >> loops at run time. If the PMD rule is better than JIT, then that is jus= t a >> bonus for the programmer. I suspect the PMD rule can be better than JIT= . >> If I understand correctly, JIT is limited to looking at what is inlined = due >> to runtime constraints. PMD can has the time to go much deeper. Also, = if >> the loop calls Runnable.run(), then PMD can look at all classes that >> implement Runnable. Yes, this will mean false negatives, but as long as= it >> is better than JIT who cares. >> >> If the PMD rule cannot be as good as JIT, then the PMD rule will catch >> most unintentional infinite loops and has a few false negatives for the >> nontrivial things. This is much better than no PMD rule. However, for >> those that use Graal, the PMD rule can be just as good as Graal since Gr= aal >> produces a single executable (i.e. a closed system). >> >> On Thu, Jul 22, 2021 at 7:38 AM Alex Otenko <[email protected]> >> wrote: >> >>> I think the problem is still the halting problem. You only have the tex= t >>> of the program, and you need to decide not only that quit=3Dtrue exists= , but >>> that it is reachable from the loop body. >>> >>> There are trivial cases where you can do this, but the world is full of >>> nontrivial things. Say, createRandom...NP sets quit=3Dtrue. Now what? S= ay, a >>> subclass overrides createRandom...NP. Now what? Say, you call someone t= hat >>> has reference to this, and calls createRandom...NP. Now what? Is it the >>> same instance or not? >>> >>> Etc, etc, etc >>> >>> The bottom line is: often there is no simple answer to a complex >>> problem, and infinitely often there is no answer. >>> >>> Alex >>> >>> >>> On Thu, 22 Jul 2021, 13:46 Nathan Reynolds via Concurrency-interest, < >>> [email protected]> wrote: >>> >>>> It is not quite the halting problem. The halting problem asks if the >>>> computation ends. The PMD rule asks if among the many branches inside= the >>>> loop's call tree if the exit variable is set. It does not care if the >>>> branch is never taken. >>>> >>>> Consider this code... >>>> >>>> private boolean quit; >>>> >>>> while (!quit) >>>> { >>>> createRandomAlgorithmInPforNP(); >>>> >>>> if (doesAlgorithmWork()) >>>> { >>>> quit =3D true; >>>> } >>>> } >>>> >>>> The method createRandomAlgorithmInPforNP() creates a random algorithm >>>> that runs in polynomial time and hopefully solves a NP problem. The m= ethod >>>> doesAlgorithmWork() tests the created algorithm to see if it works. T= his >>>> is an example of a halting problem. We don't 100% know if an algorith= m >>>> will ever be found and hence if the loop will run forever. >>>> >>>> But, this does not matter for the PMD rule. The PMD rule only cares >>>> that there is a "quit =3D true" in the loop body (or in the call tree)= . >>>> Why? The PMD rule is looking to see if "while (!quit)" can be hoisted= out >>>> of the loop thus creating an infinite loop. It will execute the same = logic >>>> that JIT does to determine if "while (!quit)" can be hoisted. We have >>>> working code (i.e. JIT) that we can use to implement the PMD rule. >>>> >>>> On Thu, Jul 22, 2021 at 2:35 AM Andrew Haley via Concurrency-interest = < >>>> [email protected]> wrote: >>>> >>>>> On 7/21/21 4:50 PM, Nathan Reynolds via Concurrency-interest wrote: >>>>> >>>>> > Sounds like a job for a linter. For easier cases, an easy PMD rule >>>>> > will catch such a problem. For harder cases, the PMD rule will nee= d >>>>> > to traverse the call tree to see if a thread executing the loop >>>>> > could change the field. If not, flag a problem to the programmer. >>>>> >>>>> I suspect that getting this right (no false positives or negatives) i= s >>>>> equivalent to the halting problem, i.e. it's uncomputable. The best >>>>> you can say is that if an expression used as the exit condition of a >>>>> loop has a term hoisted from memory, the loop might not terminate. >>>>> >>>>> However, while linting for that provides some information to the naiv= e >>>>> programmer, it "solves" the problem of infinite loops but ignores >>>>> silently returning false results. >>>>> >>>>> -- >>>>> 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 >>>> >>> _______________________________________________ >> Concurrency-interest mailing list >> [email protected] >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >> > --000000000000d5cdd005c7bcd34b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"auto">:) concurrency libraries create a sense of security.<div = dir=3D"auto"><br></div><div dir=3D"auto">But in the end you have to tackle = ordering of events, possible interleavings, lifetimes and ownership of thin= gs become unclear, who owns errors, and how to get them to the correct plac= e in the right order. To say nothing of expression problem: loops are repla= ced with chains of events, and become indistinguishable from recursion.</di= v><div dir=3D"auto"><br></div><div dir=3D"auto">So you get rid of a lot of = support the language provides for you, all for the security through obscuri= ty.</div><div dir=3D"auto"><br></div><div dir=3D"auto">In other words, race= conditions happen even in single-threaded languages like javascript or pyt= hon.</div><div dir=3D"auto"><br></div><div dir=3D"auto">Alex</div></div><br= ><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Thu, 2= 2 Jul 2021, 20:15 Joe Bowbeer, <<a href=3D"mailto:[email protected]"= >[email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_q= uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e= x"><div dir=3D"auto">In my 20+ years of reviewing Java code, my best indica= tor (red flag) for the presence of bugs has been the existence of synchroni= zed methods and/or volatile fields.</div><div dir=3D"auto"><br></div><div d= ir=3D"auto">Programming concurrency at this low level (in Java) is for expe= rts only; whenever mere mortals try it, I can almost guarantee that I will = find a bug.</div><div dir=3D"auto"><br></div><div dir=3D"auto">The only hop= e for beginners is to leverage single-threaded subsystems and higher-level = concurrency patterns.</div><div dir=3D"auto"><br></div><div dir=3D"auto">In= summary, making volatile the default would make it harder for me to find b= ugs =F0=9F=98=80</div><div><br><div class=3D"gmail_quote"><div dir=3D"ltr" = class=3D"gmail_attr">On Thu, Jul 22, 2021 at 7:40 AM Nathan Reynolds via Co= ncurrency-interest <<a href=3D"mailto:[email protected]= " target=3D"_blank" rel=3D"noreferrer">[email protected]</= a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 = 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div= >JIT has to decide if the loop condition can be hoisted.=C2=A0 JIT halts th= e hoisting optimization even on the world "full of nontrivial things&q= uot;... and if not the JIT team gets a bug to fix.=C2=A0 Hence, I suspect J= IT is conservative on how deep it tries to examine to figure out if the con= dition can be hoisted.=C2=A0 I suspect that when JIT does not know what the= destination is (e.g. Runnable.run()), then it halts.<br></div><div><br></d= iv><div>So, the PMD rule needs to be at least as good as JIT at determining= if the variable can be hoisted.=C2=A0 This will prevent unintentional infi= nite loops at run time.=C2=A0 If the PMD rule is better than JIT, then that= is just a bonus for the programmer.=C2=A0 I suspect the PMD rule can be be= tter than JIT.=C2=A0 If I understand correctly, JIT is limited to looking a= t what is inlined due to runtime constraints.=C2=A0 PMD can has the time to= go much deeper.=C2=A0 Also, if the loop calls Runnable.run(), then PMD can= look at all classes that implement Runnable.=C2=A0 Yes, this will mean fal= se negatives, but as long as it is better than JIT who cares.<br></div><div= ><br></div><div>If the PMD rule cannot be as good as JIT, then the PMD rule= will catch most unintentional infinite loops and has a few false negatives= for the nontrivial things.=C2=A0 This is much better than no PMD rule.=C2= =A0 However, for those that use Graal, the PMD rule can be just as good as = Graal since Graal produces a single executable (i.e. a closed system).<br><= /div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_a= ttr">On Thu, Jul 22, 2021 at 7:38 AM Alex Otenko <<a href=3D"mailto:olek= [email protected]" target=3D"_blank" rel=3D"noreferrer">oleksandr.oten= [email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_quote" styl= e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin= g-left:1ex"><div dir=3D"auto">I think the problem is still the halting prob= lem. You only have the text of the program, and you need to decide not only= that quit=3Dtrue exists, but that it is reachable from the loop body.<div = dir=3D"auto"><br></div><div dir=3D"auto">There are trivial cases where you = can do this, but the world is full of nontrivial things. Say, createRandom.= ..NP sets quit=3Dtrue. Now what? Say, a subclass overrides createRandom...N= P. Now what? Say, you call someone that has reference to this, and calls cr= eateRandom...NP. Now what? Is it the same instance or not?</div><div dir=3D= "auto"><br></div><div dir=3D"auto">Etc, etc, etc</div><div dir=3D"auto"><br= ></div><div dir=3D"auto">The bottom line is: often there is no simple answe= r to a complex problem, and infinitely often there is no answer.</div><div = dir=3D"auto"><br></div><div dir=3D"auto">Alex=C2=A0</div><br><br><div class= =3D"gmail_quote" dir=3D"auto"><div dir=3D"ltr" class=3D"gmail_attr">On Thu,= 22 Jul 2021, 13:46 Nathan Reynolds via Concurrency-interest, <<a href= =3D"mailto:[email protected]" target=3D"_blank" rel=3D"nor= eferrer">[email protected]</a>> wrote:<br></div><blockq= uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p= x solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>It is not = quite the halting problem.=C2=A0 The halting problem asks if the computatio= n ends.=C2=A0 The PMD rule asks if among the many branches inside the loop&= #39;s call tree if the exit variable is set.=C2=A0 It does not care if the = branch is never taken.</div><div><br></div><div>Consider this code...</div>= <div><br></div><div>private boolean quit;<br></div><div><br></div><div>whil= e (!quit)</div><div>{</div><div>=C2=A0=C2=A0 createRandomAlgorithmInPforNP(= );</div><div><br></div><div>=C2=A0=C2=A0 if (doesAlgorithmWork())</div><div= >=C2=A0=C2=A0 {</div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 quit =3D true;<br>= </div><div>=C2=A0=C2=A0 }=C2=A0 <br></div><div>}<br></div><div><br></div><d= iv>The method createRandomAlgorithmInPforNP() creates a random algorithm th= at runs in polynomial time and hopefully solves a NP problem.=C2=A0 The met= hod doesAlgorithmWork() tests the created algorithm to see if it works.=C2= =A0 This is an example of a halting problem.=C2=A0 We don't 100% know i= f an algorithm will ever be found and hence if the loop will run forever.</= div><div><br></div><div>But, this does not matter for the PMD rule.=C2=A0 T= he PMD rule only cares that there is a "quit =3D true" in the loo= p body (or in the call tree).=C2=A0 Why?=C2=A0 The PMD rule is looking to s= ee if "while (!quit)" can be hoisted out of the loop thus creatin= g an infinite loop.=C2=A0 It will execute the same logic that JIT does to d= etermine if "while (!quit)" can be hoisted.=C2=A0 We have working= code (i.e. JIT) that we can use to implement the PMD rule.</div></div><br>= <div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Thu, Ju= l 22, 2021 at 2:35 AM Andrew Haley via Concurrency-interest <<a href=3D"= mailto:[email protected]" rel=3D"noreferrer noreferrer" ta= rget=3D"_blank">[email protected]</a>> wrote:<br></div>= <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-= left:1px solid rgb(204,204,204);padding-left:1ex">On 7/21/21 4:50 PM, Natha= n Reynolds via Concurrency-interest wrote:<br> <br> > Sounds like a job for a linter.=C2=A0 For easier cases, an easy PMD ru= le<br> > will catch such a problem.=C2=A0 For harder cases, the PMD rule will n= eed<br> > to traverse the call tree to see if a thread executing the loop<br> > could change the field.=C2=A0 If not, flag a problem to the programmer= .<br> <br> I suspect that getting this right (no false positives or negatives) is<br> equivalent to the halting problem, i.e. it's uncomputable. The best<br> you can say is that if an expression used as the exit condition of a<br> loop has a term hoisted from memory, the loop might not terminate.<br> <br> However, while linting for that provides some information to the naive<br> programmer, it "solves" the problem of infinite loops but ignores= <br> silently returning false results.<br> <br> -- <br> Andrew Haley=C2=A0 (he/him)<br> Java Platform Lead Engineer<br> Red Hat UK Ltd. <<a href=3D"https://www.redhat.com" rel=3D"noreferrer no= referrer noreferrer" target=3D"_blank">https://www.redhat.com</a>><br> <a href=3D"https://keybase.io/andrewhaley" rel=3D"noreferrer noreferrer nor= eferrer" target=3D"_blank">https://keybase.io/andrewhaley</a><br> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671<br> <br> _______________________________________________<br> Concurrency-interest mailing list<br> <a href=3D"mailto:[email protected]" rel=3D"noreferrer nor= eferrer" target=3D"_blank">[email protected]</a><br> <a href=3D"http://cs.oswego.edu/mailman/listinfo/concurrency-interest" rel= =3D"noreferrer noreferrer noreferrer" target=3D"_blank">http://cs.oswego.ed= u/mailman/listinfo/concurrency-interest</a><br> </blockquote></div> _______________________________________________<br> Concurrency-interest mailing list<br> <a href=3D"mailto:[email protected]" rel=3D"noreferrer nor= eferrer" target=3D"_blank">[email protected]</a><br> <a href=3D"http://cs.oswego.edu/mailman/listinfo/concurrency-interest" rel= =3D"noreferrer noreferrer noreferrer" target=3D"_blank">http://cs.oswego.ed= u/mailman/listinfo/concurrency-interest</a><br> </blockquote></div></div> </blockquote></div> _______________________________________________<br> Concurrency-interest mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank" rel= =3D"noreferrer">[email protected]</a><br> <a href=3D"http://cs.oswego.edu/mailman/listinfo/concurrency-interest" rel= =3D"noreferrer noreferrer" target=3D"_blank">http://cs.oswego.edu/mailman/l= istinfo/concurrency-interest</a><br> </blockquote></div></div> </blockquote></div> --000000000000d5cdd005c7bcd34b-- --===============8527686665693390798== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KQ29uY3VycmVu Y3ktaW50ZXJlc3QgbWFpbGluZyBsaXN0CkNvbmN1cnJlbmN5LWludGVyZXN0QGNzLm9zd2Vnby5l ZHUKaHR0cDovL2NzLm9zd2Vnby5lZHUvbWFpbG1hbi9saXN0aW5mby9jb25jdXJyZW5jeS1pbnRl cmVzdAo= --===============8527686665693390798==--