Reputation: 21978
With following class,
// This class should be thread-safe!!!
class BankAccount {
private long balance; // Should it be volatile?
synchronized void deposit(long amount) {
// ...
balance += amount;
}
synchronized void withdraw(long amount) {
// ...
balance -= amount;
}
}
Should I add volatile
to balance
field?
Upvotes: 4
Views: 418
Reputation: 96385
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.
Upvotes: 5
Reputation: 28269
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.
Upvotes: 4