Is the return statement atomic?












10















I pasted some code about Java concurrency:



public class ValueLatch <T> {

@GuardedBy("this") private T value = null;
private final CountDownLatch done = new CountDownLatch(1);

public boolean isSet() {
return (done.getCount() == 0);
}

public synchronized void setValue(T newValue) {
if (!isSet()) {
value = newValue;
done.countDown();
}
}

public T getValue() throws InterruptedException {
done.await();
synchronized (this) {
return value;
}
}

}


Why does return value; need to be synchronized???



Is the return statement not atomic??










share|improve this question





























    10















    I pasted some code about Java concurrency:



    public class ValueLatch <T> {

    @GuardedBy("this") private T value = null;
    private final CountDownLatch done = new CountDownLatch(1);

    public boolean isSet() {
    return (done.getCount() == 0);
    }

    public synchronized void setValue(T newValue) {
    if (!isSet()) {
    value = newValue;
    done.countDown();
    }
    }

    public T getValue() throws InterruptedException {
    done.await();
    synchronized (this) {
    return value;
    }
    }

    }


    Why does return value; need to be synchronized???



    Is the return statement not atomic??










    share|improve this question



























      10












      10








      10


      1






      I pasted some code about Java concurrency:



      public class ValueLatch <T> {

      @GuardedBy("this") private T value = null;
      private final CountDownLatch done = new CountDownLatch(1);

      public boolean isSet() {
      return (done.getCount() == 0);
      }

      public synchronized void setValue(T newValue) {
      if (!isSet()) {
      value = newValue;
      done.countDown();
      }
      }

      public T getValue() throws InterruptedException {
      done.await();
      synchronized (this) {
      return value;
      }
      }

      }


      Why does return value; need to be synchronized???



      Is the return statement not atomic??










      share|improve this question
















      I pasted some code about Java concurrency:



      public class ValueLatch <T> {

      @GuardedBy("this") private T value = null;
      private final CountDownLatch done = new CountDownLatch(1);

      public boolean isSet() {
      return (done.getCount() == 0);
      }

      public synchronized void setValue(T newValue) {
      if (!isSet()) {
      value = newValue;
      done.countDown();
      }
      }

      public T getValue() throws InterruptedException {
      done.await();
      synchronized (this) {
      return value;
      }
      }

      }


      Why does return value; need to be synchronized???



      Is the return statement not atomic??







      java concurrency






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 13 '18 at 20:40









      Boann

      36.8k1288121




      36.8k1288121










      asked Nov 13 '18 at 15:51









      Li YunleiLi Yunlei

      536




      536
























          3 Answers
          3






          active

          oldest

          votes


















          8














          The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.



          The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.



          I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.






          share|improve this answer


























          • the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

            – Li Yunlei
            Nov 14 '18 at 15:03











          • Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

            – Matt Timmermans
            Nov 14 '18 at 15:48













          • @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

            – Hoopje
            Nov 16 '18 at 11:50













          • Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

            – Hoopje
            Nov 16 '18 at 11:56



















          2














          The return statement needs to perform a read operation over value.



          The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.



          For that reason, the return should be synchronized.






          share|improve this answer



















          • 6





            Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

            – Matt Timmermans
            Nov 13 '18 at 18:46











          • Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

            – michid
            Nov 13 '18 at 21:54











          • I was misinformed, thank you for correcting me. So it is useless to force synchronization here

            – ricol070
            Nov 14 '18 at 18:22



















          2














          return value does not need to be synchronized:




          • reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."

          • each thread reading value is guaranteed to so see its latest value as according to the Java Memory Model value = newValue happens-before done.countDown(), which happens-before done.await(), which happens-before return value. By transitivity value = newValue thus happens-before return value.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284720%2fis-the-return-statement-atomic%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            8














            The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.



            The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.



            I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.






            share|improve this answer


























            • the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

              – Li Yunlei
              Nov 14 '18 at 15:03











            • Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

              – Matt Timmermans
              Nov 14 '18 at 15:48













            • @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

              – Hoopje
              Nov 16 '18 at 11:50













            • Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

              – Hoopje
              Nov 16 '18 at 11:56
















            8














            The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.



            The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.



            I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.






            share|improve this answer


























            • the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

              – Li Yunlei
              Nov 14 '18 at 15:03











            • Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

              – Matt Timmermans
              Nov 14 '18 at 15:48













            • @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

              – Hoopje
              Nov 16 '18 at 11:50













            • Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

              – Hoopje
              Nov 16 '18 at 11:56














            8












            8








            8







            The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.



            The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.



            I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.






            share|improve this answer















            The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.



            The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.



            I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 13 '18 at 18:29

























            answered Nov 13 '18 at 18:22









            Matt TimmermansMatt Timmermans

            19k11532




            19k11532













            • the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

              – Li Yunlei
              Nov 14 '18 at 15:03











            • Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

              – Matt Timmermans
              Nov 14 '18 at 15:48













            • @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

              – Hoopje
              Nov 16 '18 at 11:50













            • Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

              – Hoopje
              Nov 16 '18 at 11:56



















            • the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

              – Li Yunlei
              Nov 14 '18 at 15:03











            • Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

              – Matt Timmermans
              Nov 14 '18 at 15:48













            • @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

              – Hoopje
              Nov 16 '18 at 11:50













            • Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

              – Hoopje
              Nov 16 '18 at 11:56

















            the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

            – Li Yunlei
            Nov 14 '18 at 15:03





            the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?

            – Li Yunlei
            Nov 14 '18 at 15:03













            Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

            – Matt Timmermans
            Nov 14 '18 at 15:48







            Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.

            – Matt Timmermans
            Nov 14 '18 at 15:48















            @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

            – Hoopje
            Nov 16 '18 at 11:50







            @MattTimmermans Why? When Thread A (calling setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?

            – Hoopje
            Nov 16 '18 at 11:50















            Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

            – Hoopje
            Nov 16 '18 at 11:56





            Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the CountDownLatch JavaDoc. Never mind :-)

            – Hoopje
            Nov 16 '18 at 11:56













            2














            The return statement needs to perform a read operation over value.



            The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.



            For that reason, the return should be synchronized.






            share|improve this answer



















            • 6





              Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

              – Matt Timmermans
              Nov 13 '18 at 18:46











            • Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

              – michid
              Nov 13 '18 at 21:54











            • I was misinformed, thank you for correcting me. So it is useless to force synchronization here

              – ricol070
              Nov 14 '18 at 18:22
















            2














            The return statement needs to perform a read operation over value.



            The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.



            For that reason, the return should be synchronized.






            share|improve this answer



















            • 6





              Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

              – Matt Timmermans
              Nov 13 '18 at 18:46











            • Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

              – michid
              Nov 13 '18 at 21:54











            • I was misinformed, thank you for correcting me. So it is useless to force synchronization here

              – ricol070
              Nov 14 '18 at 18:22














            2












            2








            2







            The return statement needs to perform a read operation over value.



            The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.



            For that reason, the return should be synchronized.






            share|improve this answer













            The return statement needs to perform a read operation over value.



            The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.



            For that reason, the return should be synchronized.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 13 '18 at 17:27









            ricol070ricol070

            435211




            435211








            • 6





              Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

              – Matt Timmermans
              Nov 13 '18 at 18:46











            • Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

              – michid
              Nov 13 '18 at 21:54











            • I was misinformed, thank you for correcting me. So it is useless to force synchronization here

              – ricol070
              Nov 14 '18 at 18:22














            • 6





              Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

              – Matt Timmermans
              Nov 13 '18 at 18:46











            • Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

              – michid
              Nov 13 '18 at 21:54











            • I was misinformed, thank you for correcting me. So it is useless to force synchronization here

              – ricol070
              Nov 14 '18 at 18:22








            6




            6





            Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

            – Matt Timmermans
            Nov 13 '18 at 18:46





            Java generics use type erasure, so you do know value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.

            – Matt Timmermans
            Nov 13 '18 at 18:46













            Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

            – michid
            Nov 13 '18 at 21:54





            Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

            – michid
            Nov 13 '18 at 21:54













            I was misinformed, thank you for correcting me. So it is useless to force synchronization here

            – ricol070
            Nov 14 '18 at 18:22





            I was misinformed, thank you for correcting me. So it is useless to force synchronization here

            – ricol070
            Nov 14 '18 at 18:22











            2














            return value does not need to be synchronized:




            • reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."

            • each thread reading value is guaranteed to so see its latest value as according to the Java Memory Model value = newValue happens-before done.countDown(), which happens-before done.await(), which happens-before return value. By transitivity value = newValue thus happens-before return value.






            share|improve this answer




























              2














              return value does not need to be synchronized:




              • reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."

              • each thread reading value is guaranteed to so see its latest value as according to the Java Memory Model value = newValue happens-before done.countDown(), which happens-before done.await(), which happens-before return value. By transitivity value = newValue thus happens-before return value.






              share|improve this answer


























                2












                2








                2







                return value does not need to be synchronized:




                • reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."

                • each thread reading value is guaranteed to so see its latest value as according to the Java Memory Model value = newValue happens-before done.countDown(), which happens-before done.await(), which happens-before return value. By transitivity value = newValue thus happens-before return value.






                share|improve this answer













                return value does not need to be synchronized:




                • reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."

                • each thread reading value is guaranteed to so see its latest value as according to the Java Memory Model value = newValue happens-before done.countDown(), which happens-before done.await(), which happens-before return value. By transitivity value = newValue thus happens-before return value.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 13 '18 at 21:51









                michidmichid

                5,31121837




                5,31121837






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284720%2fis-the-return-statement-atomic%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    List item for chat from Array inside array React Native

                    Thiostrepton

                    Caerphilly