Should you synchronize access to properties in Java?
This question already has an answer here:
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:
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:
Thread can get into a given method / code block. This is useful for complex calculations. 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:
volatile keyword, eg private voltaile int sum; . For the volatile primitives we can use the normal getters/setters. final primitives, we can use the normal setters - no getters. Thanks for pointing it out :) Atomic values like AtomicInteger , AtomicLong and AtomicReference , ... 上一篇: 模板和重载
下一篇: 你应该同步访问Java中的属性吗?
