Reputation: 467
I'm learning java concurrency and used a Bank Account that is shared among multiple people example to try to practice principles of concurrency.
This is my Account class.
public class Account(){
private int balance = 0;
public int getBalance(){ return balance}
public synchronized void deposit(int val){//..}
void synchronized void withdrawal(int val){//..}
}
deposit and withdrawal methods are synchronized because they directly modify the state of the Account object, so to avoid data corruption if multiple users try to change it at the same time.
On the other hand, getBalance()
does not change the state of the Account object. But I was thinking that if getBalance()
is called while a deposit or withdrawal is happening, it will return an outdated value. What is the standard practice, to synchronize or not to synchronize getBalance()
?
Upvotes: 4
Views: 149
Reputation: 4799
if getBalance() is called while a deposit or withdrawal is happening, it will return the outdated value
There's no outdated value while these processes are running, simply because you can not say for sure whether they're going to fail or not (I'm assuming you're not using balance
field for intermediate state representation).
So the question actually is - do you want to read the most recent state of balance and do it despite of whether withdrawal or deposit is running? Or, you want to wait until one of the processes finishes, so you can read the value?
In the first case you can simply make the field volatile (private volatile int balance = 0;
) to ensure memory visibility between threads.
In the second case, simply use synchronized
.
Upvotes: 3
Reputation: 450
you need to synchronize an Object not literal, as synchronize only the Object which is critical for better performance than function.
Object lock = new Object();
public class Account(){
private int balance = 0;
public int getBalance(){ synchronized (lock){return balance} }
public void deposit(int val){synchronized (lock){...} }
void withdrawal(int val){synchronized (lock){...} }
}
}
This way you can add more logic inside the function to perform better and keep balance synchronized on updates.
Upvotes: 1
Reputation: 143
IMHO, synchronized is needed to avoid 'race condition' when you are trying to modify the property. https://netjs.blogspot.com/2015/06/race-condition-in-java-multi-threading.html
So that if you're modifying it you could predict the result. Otherwise, you cannot guarantee what would be the output.
Besides that I would, probably, wrap the balance property into some AtomicInteger or at least mark it as volatile.
Upvotes: 2