Should you synchronize access to properties in Java?

This question already has an answer here:

  • Should getters and setters be synchronized? 4 answers

  • My question is why?

    To ensure memory visibility across threads.

    What would be the use of synchronizing getId method?

    Every synchronized getId call guarantees that the given id is up-to-date for the moment of ending of the operation (releasing a lock).

    Or what could happen if I don't synchronize it?

    A stale getId value will be used to update others variables which will affect correctness.


    Every method that operates with the shared state of a variable needs some kind of synchronisation. The getter provides the state, so synchronisation is required. The setter changes the state, synchronisation is also required.

    Imagine a thread that changes an id (a writer), and a thread that reads that id (a reader). If these threads don't synchronize their operations by the same lock, weird things may happen when the threads are running simultaneously:

  • The reader reads the variable while a writer is in the middle of its execution.
  • The reader can see a partially (or incorrectly) initialized/set value.
  • The state can be out-of-date for the reader.

  • Synchronized specifies that any access to the variable is limited to one thread at a time. So it will lock to prevent others from modifying it during the completion of the function. You can see more details along with official documentation about that here: What does 'synchronized' mean?

    As far as what could happen, there is a fairly simple example but not using ID since that shouldn't change. Lets say you have a property called "cost" (the name is irrelevant) with a value of 10 and two threads that have access to that property that are running at the same time.

    The process is not synchronized:

    Process A - Calls to change the cost to 20.

    Process B - Calls to get the cost

    Process B - Gets the cost = 10

    Process A - Finishes modifying the cost.

    So even though the cost was 20 as per thread A changing it, the property was not updated before B retrieved its value, causing the wrong information to be received.


    The synchronized keyword has two effects:

  • Only one Thread can get into a given method / code block. This is useful for complex calculations.
  • Changes made by one Thread are going to be visible by another Thread . By default it's not true. The jvm / the hardware might cache certain values for certain Threads . You can read more on this here.
  • Note: the statements above are true if and only if the synchronized blocks refer to the same object. Since we're talking about getters and setters, this will be true: they will lock against the same object.

    So yes, we need to use synchronized getters and setters. There are a few alternatives though:

  • For primitives we can use the volatile keyword, eg private voltaile int sum; . For the volatile primitives we can use the normal getters/setters.
  • For final primitives, we can use the normal setters - no getters. Thanks for pointing it out :)
  • We can use the Atomic values like AtomicInteger , AtomicLong and AtomicReference , ...
  • 链接地址: http://www.djcxy.com/p/40988.html

    上一篇: 模板和重载

    下一篇: 你应该同步访问Java中的属性吗?