With following class,
// This class should be thread-safe!!!
class BankAccount {
private long balance; // Should it
No, compared with synchronized
keyword, volatile
is lightweight.
volatile
can gurantee the reader thread always get fresh balance
value, but it can not make balance += amount;
atomic. synchronized
can do both.
You don’t need volatile
in the code shown, because the variable is used only within the synchronized
methods. The synchronized
methods make sure that the variable’s contents are visible and not stale, and also make sure that the operations performed within each synchronized
method are not interfered with by concurrently running threads. The volatile
keyword is redundant here, it only makes sure the variable’s contents are visible.
If you want the variable’s value to be visible to threads that don’t enter a synchronized
instance method on this object (maybe you’d like it to be used in methods that don’t acquire a lock on the instance), then in that case keeping it volatile
would make sense.
If you took away the synchronized
keywords and left the variable volatile
, you’d have a problem, because although volatile
makes sure updates are visible it doesn’t make sure the updates are atomic. The +=
and -=
operations here are not atomic and can be interfered with by concurrently-running threads.
Alternatively consider using an AtomicLong instead, in this example you might not need the synchronized
keyword (depending on what the code in //... does). Methods like addAndGet perform their changes to the value stored atomically. For most things where you would have used volatile before, the Atomic classes can do a better job.