Java – synchronization difference between field reading and volatile

In a good article with some concurrency tips, an example is optimized to the following lines:

double getBalance() {
    Account acct = verify(name,password);
    synchronized(acct) { return acct.balance; }
}

If I understand correctly, the key point of synchronization is to ensure that the value of acct.balance read by this thread is up-to-date, and any pending writes to the fields of objects in acct.balance are also written to main memory

This example makes me think: is it more effective to just declare acct.balance (i.e. domain balance of the account)? It should be more efficient, save all synchronization of access to acct.balance, and do not lock the entire acct object Did I miss anything?

Solution

You're right. Volatile provides visibility assurance Synchronization provides visibility assurance and serialization of protected code segments For very simple cases, volatile is enough, but using volatile instead of synchronization is easy to get into trouble

If you think the account has a way to adjust the balance, the volatility is not good enough

public void add(double amount)
{
   balance = balance + amount;
}

So if the balance is fluctuating and there is no other synchronization, we have a problem If two threads try and call add () together, you may have a "missed" update. The following happens

Thread1 - Calls add(100)
Thread2 - Calls add(200)
Thread1 - Read balance (0)
Thread2 - Read balance (0)
Thread1 - Compute new balance (0+100=100)
Thread2 - Compute new balance (0+200=200)
Thread1 - Write balance = 100
Thread2 - Write balance = 200 (WRONG!)

Obviously, this is wrong because two threads read the current value and update it independently, and then write it back (read, calculate, write) Volatile doesn't help here, so you need synchronization to ensure that one thread completes the entire update before other threads start

I generally find that if I think "I can use volatile instead of synchronization" when writing some code, the answer may be "yes", but it is not worth the benefit (secondary performance) to accurately determine its time / effort and the risk of error

Except for a well - written account class, it can handle all synchronization logic internally, so callers don't have to worry

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>