Java: Make all fields either final or volatile?











up vote
6
down vote

favorite
2












If I have an object which is shared between threads, it seems to me that every field should be either final or volatile, with the following reasoning:




  • if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value. Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.


  • if the field should never change, make it final.



However, I could not find anything about this, so I wonder whether this logic is flawed or just too obvious?



EDIT of course instead of volatile one might use a final AtomicReference or similar.



EDIT for example, see Is getter method an alternative to volatile in Java?



EDIT to avoid confusions: This question is about cache invalidation! If two threads operate on the same object, the fields of the objects can be cached (per thread), if they are not declared volatile. How can I guarantee that the cache is invalidated properly?



FINAL EDIT Thanks to @Peter Lawrey who pointed me to JLS §17 (Java memory model). As far as I see, it states that synchronization establishes a happens-before relation between operations, so that a thread sees the updates from another thread if those updates "happened-before", e.g. if getter and setter for a non-volatile field are synchronized.










share|improve this question




















  • 1




    Merely a synchronization on the methods which access said field is insufficient - no, synchronization is "stronger" than volatile. It means you won't even enter the method if another thread is in it, so you only enter after the other one exited and finished changing the value.
    – daniu
    2 hours ago










  • the problem is that each thread can have its own cached version, so that thread 2 still may see the old version after thread 1 has updated it. tutorials.jenkov.com/java-concurrency/volatile.html
    – Moritz
    1 hour ago















up vote
6
down vote

favorite
2












If I have an object which is shared between threads, it seems to me that every field should be either final or volatile, with the following reasoning:




  • if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value. Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.


  • if the field should never change, make it final.



However, I could not find anything about this, so I wonder whether this logic is flawed or just too obvious?



EDIT of course instead of volatile one might use a final AtomicReference or similar.



EDIT for example, see Is getter method an alternative to volatile in Java?



EDIT to avoid confusions: This question is about cache invalidation! If two threads operate on the same object, the fields of the objects can be cached (per thread), if they are not declared volatile. How can I guarantee that the cache is invalidated properly?



FINAL EDIT Thanks to @Peter Lawrey who pointed me to JLS §17 (Java memory model). As far as I see, it states that synchronization establishes a happens-before relation between operations, so that a thread sees the updates from another thread if those updates "happened-before", e.g. if getter and setter for a non-volatile field are synchronized.










share|improve this question




















  • 1




    Merely a synchronization on the methods which access said field is insufficient - no, synchronization is "stronger" than volatile. It means you won't even enter the method if another thread is in it, so you only enter after the other one exited and finished changing the value.
    – daniu
    2 hours ago










  • the problem is that each thread can have its own cached version, so that thread 2 still may see the old version after thread 1 has updated it. tutorials.jenkov.com/java-concurrency/volatile.html
    – Moritz
    1 hour ago













up vote
6
down vote

favorite
2









up vote
6
down vote

favorite
2






2





If I have an object which is shared between threads, it seems to me that every field should be either final or volatile, with the following reasoning:




  • if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value. Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.


  • if the field should never change, make it final.



However, I could not find anything about this, so I wonder whether this logic is flawed or just too obvious?



EDIT of course instead of volatile one might use a final AtomicReference or similar.



EDIT for example, see Is getter method an alternative to volatile in Java?



EDIT to avoid confusions: This question is about cache invalidation! If two threads operate on the same object, the fields of the objects can be cached (per thread), if they are not declared volatile. How can I guarantee that the cache is invalidated properly?



FINAL EDIT Thanks to @Peter Lawrey who pointed me to JLS §17 (Java memory model). As far as I see, it states that synchronization establishes a happens-before relation between operations, so that a thread sees the updates from another thread if those updates "happened-before", e.g. if getter and setter for a non-volatile field are synchronized.










share|improve this question















If I have an object which is shared between threads, it seems to me that every field should be either final or volatile, with the following reasoning:




  • if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value. Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.


  • if the field should never change, make it final.



However, I could not find anything about this, so I wonder whether this logic is flawed or just too obvious?



EDIT of course instead of volatile one might use a final AtomicReference or similar.



EDIT for example, see Is getter method an alternative to volatile in Java?



EDIT to avoid confusions: This question is about cache invalidation! If two threads operate on the same object, the fields of the objects can be cached (per thread), if they are not declared volatile. How can I guarantee that the cache is invalidated properly?



FINAL EDIT Thanks to @Peter Lawrey who pointed me to JLS §17 (Java memory model). As far as I see, it states that synchronization establishes a happens-before relation between operations, so that a thread sees the updates from another thread if those updates "happened-before", e.g. if getter and setter for a non-volatile field are synchronized.







java multithreading volatile final






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 41 mins ago

























asked 2 hours ago









Moritz

31119




31119








  • 1




    Merely a synchronization on the methods which access said field is insufficient - no, synchronization is "stronger" than volatile. It means you won't even enter the method if another thread is in it, so you only enter after the other one exited and finished changing the value.
    – daniu
    2 hours ago










  • the problem is that each thread can have its own cached version, so that thread 2 still may see the old version after thread 1 has updated it. tutorials.jenkov.com/java-concurrency/volatile.html
    – Moritz
    1 hour ago














  • 1




    Merely a synchronization on the methods which access said field is insufficient - no, synchronization is "stronger" than volatile. It means you won't even enter the method if another thread is in it, so you only enter after the other one exited and finished changing the value.
    – daniu
    2 hours ago










  • the problem is that each thread can have its own cached version, so that thread 2 still may see the old version after thread 1 has updated it. tutorials.jenkov.com/java-concurrency/volatile.html
    – Moritz
    1 hour ago








1




1




Merely a synchronization on the methods which access said field is insufficient - no, synchronization is "stronger" than volatile. It means you won't even enter the method if another thread is in it, so you only enter after the other one exited and finished changing the value.
– daniu
2 hours ago




Merely a synchronization on the methods which access said field is insufficient - no, synchronization is "stronger" than volatile. It means you won't even enter the method if another thread is in it, so you only enter after the other one exited and finished changing the value.
– daniu
2 hours ago












the problem is that each thread can have its own cached version, so that thread 2 still may see the old version after thread 1 has updated it. tutorials.jenkov.com/java-concurrency/volatile.html
– Moritz
1 hour ago




the problem is that each thread can have its own cached version, so that thread 2 still may see the old version after thread 1 has updated it. tutorials.jenkov.com/java-concurrency/volatile.html
– Moritz
1 hour ago












2 Answers
2






active

oldest

votes

















up vote
10
down vote



accepted










While I feel private final should probably have been the default for fields and variables with a keyword like var making it mutable, using volatile when you don't need it is




  • much slower, often around 10x slower.

  • usually doesn't give you the thread safety you need, but can make finding such bugs harder by making them less likely to appear.

  • unlike final which improves clarity by saying this shouldn't be altered, using volatile when it is not needed, is likely to be confusing as the reader tries to work out why it was made volatile.



if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value.




While this is fine for reads, consider this trivial case.



volatile int x;

x++;


This isn't thread-safe. As it's the same as



int x2 = x;
x2 = x2 + 1; // multiple threads could be executing on the same value at this point.
x = x2;


What is worse is that using volatile would make this kind of bug harder to find.




Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




synchronized gives you all the memory guarantees of volatile and more, which is why it's significantly slower.



NOTE: Just synchronized-ing every method isn't always enough either. StringBuffer has every method synchronized but is worst than useless in a multi-threaded context as it's use is likely to be error-prone.



It's too easy to assume that achieving thread safety is like sprinkling fairy dust, add some magic thread safety and your bugs go away. The problem is that thread safety is more like a bucket with many holes. Plug the biggest holes and the bugs can appear to go away, but unless you plug them all, you don't have thread safety, but it can be harder to find.



In terms of synchronzied vs volatile, this states




Other mechanisms, such as reads and writes of volatile variables and the use of classes in the java.util.concurrent package, provide alternative ways of synchronization.




https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html






share|improve this answer























  • Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
    – Moritz
    1 hour ago










  • @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
    – Peter Lawrey
    1 hour ago












  • makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
    – Moritz
    1 hour ago










  • @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
    – Peter Lawrey
    1 hour ago










  • As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
    – Moritz
    49 mins ago


















up vote
4
down vote













Making fields you don't need to change final is a good idea, irrespective of threading concerns. It makes instances of the class easier to reason about, because you can know what state it is in more easily.



In terms of making the other fields volatile:




Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




You would only see a cached value if you accessing the value outside a synchronized block.



All accesses would need to be correctly synchronized. The end of one synchronized block is guaranteed to happen before the start of another synchronized block (when synchronizing on the same monitor).



There are at least a couple of cases where you would still need to use synchronization:




  • You would want to use synchronization if you had to read and then update one or more fields atomically.


    • You may be able to avoid synchronization for certain single field updates, e.g. if you can use an Atomic* class instead of a "plain old field"; but even for a single field update, you could still require exclusive access (e.g. adding one element to a list whilst removing another).



  • Also, volatile/final may be insufficient for non-thread safe values, like an ArrayList or an array.






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',
    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%2f53738662%2fjava-make-all-fields-either-final-or-volatile%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    10
    down vote



    accepted










    While I feel private final should probably have been the default for fields and variables with a keyword like var making it mutable, using volatile when you don't need it is




    • much slower, often around 10x slower.

    • usually doesn't give you the thread safety you need, but can make finding such bugs harder by making them less likely to appear.

    • unlike final which improves clarity by saying this shouldn't be altered, using volatile when it is not needed, is likely to be confusing as the reader tries to work out why it was made volatile.



    if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value.




    While this is fine for reads, consider this trivial case.



    volatile int x;

    x++;


    This isn't thread-safe. As it's the same as



    int x2 = x;
    x2 = x2 + 1; // multiple threads could be executing on the same value at this point.
    x = x2;


    What is worse is that using volatile would make this kind of bug harder to find.




    Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




    synchronized gives you all the memory guarantees of volatile and more, which is why it's significantly slower.



    NOTE: Just synchronized-ing every method isn't always enough either. StringBuffer has every method synchronized but is worst than useless in a multi-threaded context as it's use is likely to be error-prone.



    It's too easy to assume that achieving thread safety is like sprinkling fairy dust, add some magic thread safety and your bugs go away. The problem is that thread safety is more like a bucket with many holes. Plug the biggest holes and the bugs can appear to go away, but unless you plug them all, you don't have thread safety, but it can be harder to find.



    In terms of synchronzied vs volatile, this states




    Other mechanisms, such as reads and writes of volatile variables and the use of classes in the java.util.concurrent package, provide alternative ways of synchronization.




    https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html






    share|improve this answer























    • Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
      – Moritz
      1 hour ago










    • @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
      – Peter Lawrey
      1 hour ago












    • makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
      – Moritz
      1 hour ago










    • @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
      – Peter Lawrey
      1 hour ago










    • As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
      – Moritz
      49 mins ago















    up vote
    10
    down vote



    accepted










    While I feel private final should probably have been the default for fields and variables with a keyword like var making it mutable, using volatile when you don't need it is




    • much slower, often around 10x slower.

    • usually doesn't give you the thread safety you need, but can make finding such bugs harder by making them less likely to appear.

    • unlike final which improves clarity by saying this shouldn't be altered, using volatile when it is not needed, is likely to be confusing as the reader tries to work out why it was made volatile.



    if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value.




    While this is fine for reads, consider this trivial case.



    volatile int x;

    x++;


    This isn't thread-safe. As it's the same as



    int x2 = x;
    x2 = x2 + 1; // multiple threads could be executing on the same value at this point.
    x = x2;


    What is worse is that using volatile would make this kind of bug harder to find.




    Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




    synchronized gives you all the memory guarantees of volatile and more, which is why it's significantly slower.



    NOTE: Just synchronized-ing every method isn't always enough either. StringBuffer has every method synchronized but is worst than useless in a multi-threaded context as it's use is likely to be error-prone.



    It's too easy to assume that achieving thread safety is like sprinkling fairy dust, add some magic thread safety and your bugs go away. The problem is that thread safety is more like a bucket with many holes. Plug the biggest holes and the bugs can appear to go away, but unless you plug them all, you don't have thread safety, but it can be harder to find.



    In terms of synchronzied vs volatile, this states




    Other mechanisms, such as reads and writes of volatile variables and the use of classes in the java.util.concurrent package, provide alternative ways of synchronization.




    https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html






    share|improve this answer























    • Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
      – Moritz
      1 hour ago










    • @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
      – Peter Lawrey
      1 hour ago












    • makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
      – Moritz
      1 hour ago










    • @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
      – Peter Lawrey
      1 hour ago










    • As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
      – Moritz
      49 mins ago













    up vote
    10
    down vote



    accepted







    up vote
    10
    down vote



    accepted






    While I feel private final should probably have been the default for fields and variables with a keyword like var making it mutable, using volatile when you don't need it is




    • much slower, often around 10x slower.

    • usually doesn't give you the thread safety you need, but can make finding such bugs harder by making them less likely to appear.

    • unlike final which improves clarity by saying this shouldn't be altered, using volatile when it is not needed, is likely to be confusing as the reader tries to work out why it was made volatile.



    if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value.




    While this is fine for reads, consider this trivial case.



    volatile int x;

    x++;


    This isn't thread-safe. As it's the same as



    int x2 = x;
    x2 = x2 + 1; // multiple threads could be executing on the same value at this point.
    x = x2;


    What is worse is that using volatile would make this kind of bug harder to find.




    Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




    synchronized gives you all the memory guarantees of volatile and more, which is why it's significantly slower.



    NOTE: Just synchronized-ing every method isn't always enough either. StringBuffer has every method synchronized but is worst than useless in a multi-threaded context as it's use is likely to be error-prone.



    It's too easy to assume that achieving thread safety is like sprinkling fairy dust, add some magic thread safety and your bugs go away. The problem is that thread safety is more like a bucket with many holes. Plug the biggest holes and the bugs can appear to go away, but unless you plug them all, you don't have thread safety, but it can be harder to find.



    In terms of synchronzied vs volatile, this states




    Other mechanisms, such as reads and writes of volatile variables and the use of classes in the java.util.concurrent package, provide alternative ways of synchronization.




    https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html






    share|improve this answer














    While I feel private final should probably have been the default for fields and variables with a keyword like var making it mutable, using volatile when you don't need it is




    • much slower, often around 10x slower.

    • usually doesn't give you the thread safety you need, but can make finding such bugs harder by making them less likely to appear.

    • unlike final which improves clarity by saying this shouldn't be altered, using volatile when it is not needed, is likely to be confusing as the reader tries to work out why it was made volatile.



    if the field should be changed (point to another object, update the primitive value), then the field should be volatile so that all other threads operate on the new value.




    While this is fine for reads, consider this trivial case.



    volatile int x;

    x++;


    This isn't thread-safe. As it's the same as



    int x2 = x;
    x2 = x2 + 1; // multiple threads could be executing on the same value at this point.
    x = x2;


    What is worse is that using volatile would make this kind of bug harder to find.




    Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




    synchronized gives you all the memory guarantees of volatile and more, which is why it's significantly slower.



    NOTE: Just synchronized-ing every method isn't always enough either. StringBuffer has every method synchronized but is worst than useless in a multi-threaded context as it's use is likely to be error-prone.



    It's too easy to assume that achieving thread safety is like sprinkling fairy dust, add some magic thread safety and your bugs go away. The problem is that thread safety is more like a bucket with many holes. Plug the biggest holes and the bugs can appear to go away, but unless you plug them all, you don't have thread safety, but it can be harder to find.



    In terms of synchronzied vs volatile, this states




    Other mechanisms, such as reads and writes of volatile variables and the use of classes in the java.util.concurrent package, provide alternative ways of synchronization.




    https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 1 hour ago

























    answered 1 hour ago









    Peter Lawrey

    439k55556956




    439k55556956












    • Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
      – Moritz
      1 hour ago










    • @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
      – Peter Lawrey
      1 hour ago












    • makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
      – Moritz
      1 hour ago










    • @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
      – Peter Lawrey
      1 hour ago










    • As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
      – Moritz
      49 mins ago


















    • Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
      – Moritz
      1 hour ago










    • @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
      – Peter Lawrey
      1 hour ago












    • makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
      – Moritz
      1 hour ago










    • @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
      – Peter Lawrey
      1 hour ago










    • As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
      – Moritz
      49 mins ago
















    Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
    – Moritz
    1 hour ago




    Can you please explain why, given that thread1 and thread2 hold a reference to the same object, and access is via synchronized methods only, thread 2 sees the updates of thread 1 guaranteed? I refer to e.g. tutorials.jenkov.com/java-concurrency/volatile.html This and other resources say (as far as I understand) that the fields can still be cached in different cache lines - that is, thread 2 just has to wait for the getX() to enter but it will still return the cached version. Is there any guarantee that the thread's cache is updated after obtaining the monitor or the like?
    – Moritz
    1 hour ago












    @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
    – Peter Lawrey
    1 hour ago






    @Moritz synchronization would be pointless without memory barriers to provide those guarantees. While the value is cached within the synchronized block, it will return the latest value on read and ensure anything written is visible to all threads.
    – Peter Lawrey
    1 hour ago














    makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
    – Moritz
    1 hour ago




    makes totally sense to me, but do you by chance know any point let's say in JLS where this is stated?
    – Moritz
    1 hour ago












    @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
    – Peter Lawrey
    1 hour ago




    @Moritz I have added a reference to synchronization holding a monitor and a lock, and stating voaltile is an alternative.
    – Peter Lawrey
    1 hour ago












    As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
    – Moritz
    49 mins ago




    As far as I see, from JLS §17 it follows that if accessor methods are synchronized, this introduces a happens-before relation between the accesses, and thus the second operation will see the update. Right?
    – Moritz
    49 mins ago












    up vote
    4
    down vote













    Making fields you don't need to change final is a good idea, irrespective of threading concerns. It makes instances of the class easier to reason about, because you can know what state it is in more easily.



    In terms of making the other fields volatile:




    Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




    You would only see a cached value if you accessing the value outside a synchronized block.



    All accesses would need to be correctly synchronized. The end of one synchronized block is guaranteed to happen before the start of another synchronized block (when synchronizing on the same monitor).



    There are at least a couple of cases where you would still need to use synchronization:




    • You would want to use synchronization if you had to read and then update one or more fields atomically.


      • You may be able to avoid synchronization for certain single field updates, e.g. if you can use an Atomic* class instead of a "plain old field"; but even for a single field update, you could still require exclusive access (e.g. adding one element to a list whilst removing another).



    • Also, volatile/final may be insufficient for non-thread safe values, like an ArrayList or an array.






    share|improve this answer



























      up vote
      4
      down vote













      Making fields you don't need to change final is a good idea, irrespective of threading concerns. It makes instances of the class easier to reason about, because you can know what state it is in more easily.



      In terms of making the other fields volatile:




      Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




      You would only see a cached value if you accessing the value outside a synchronized block.



      All accesses would need to be correctly synchronized. The end of one synchronized block is guaranteed to happen before the start of another synchronized block (when synchronizing on the same monitor).



      There are at least a couple of cases where you would still need to use synchronization:




      • You would want to use synchronization if you had to read and then update one or more fields atomically.


        • You may be able to avoid synchronization for certain single field updates, e.g. if you can use an Atomic* class instead of a "plain old field"; but even for a single field update, you could still require exclusive access (e.g. adding one element to a list whilst removing another).



      • Also, volatile/final may be insufficient for non-thread safe values, like an ArrayList or an array.






      share|improve this answer

























        up vote
        4
        down vote










        up vote
        4
        down vote









        Making fields you don't need to change final is a good idea, irrespective of threading concerns. It makes instances of the class easier to reason about, because you can know what state it is in more easily.



        In terms of making the other fields volatile:




        Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




        You would only see a cached value if you accessing the value outside a synchronized block.



        All accesses would need to be correctly synchronized. The end of one synchronized block is guaranteed to happen before the start of another synchronized block (when synchronizing on the same monitor).



        There are at least a couple of cases where you would still need to use synchronization:




        • You would want to use synchronization if you had to read and then update one or more fields atomically.


          • You may be able to avoid synchronization for certain single field updates, e.g. if you can use an Atomic* class instead of a "plain old field"; but even for a single field update, you could still require exclusive access (e.g. adding one element to a list whilst removing another).



        • Also, volatile/final may be insufficient for non-thread safe values, like an ArrayList or an array.






        share|improve this answer














        Making fields you don't need to change final is a good idea, irrespective of threading concerns. It makes instances of the class easier to reason about, because you can know what state it is in more easily.



        In terms of making the other fields volatile:




        Merely a synchronization on the methods which access said field is insufficient because they might return a cached value.




        You would only see a cached value if you accessing the value outside a synchronized block.



        All accesses would need to be correctly synchronized. The end of one synchronized block is guaranteed to happen before the start of another synchronized block (when synchronizing on the same monitor).



        There are at least a couple of cases where you would still need to use synchronization:




        • You would want to use synchronization if you had to read and then update one or more fields atomically.


          • You may be able to avoid synchronization for certain single field updates, e.g. if you can use an Atomic* class instead of a "plain old field"; but even for a single field update, you could still require exclusive access (e.g. adding one element to a list whilst removing another).



        • Also, volatile/final may be insufficient for non-thread safe values, like an ArrayList or an array.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 1 hour ago

























        answered 1 hour ago









        Andy Turner

        79.3k878131




        79.3k878131






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53738662%2fjava-make-all-fields-either-final-or-volatile%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

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            How to ignore python UserWarning in pytest?

            Alexandru Averescu