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中的属性吗?