Reputation: 343
I am just trying to understand... Will I achieve the same result using the below two approaches? I mostly see the first approach only. Is there anything wrong with the second approach? We can use AtomicInteger to achieve the same but just wanted to know. Can someone please clarify?
Approach#1
public class Counter {
private int counter = 0;
public int getCount() {
synchronized(this) {
return counter;
}
}
public void increment() {
synchronized(this) {
counter++;
}
}
}
Approach#2
public class Counter {
private volatile int counter = 0;
public int getCount() {
return counter;
}
public synchronized void increment() {
counter++;
}
}
Upvotes: 1
Views: 60
Reputation: 27115
You never need volatile
if you're using synchronized
. Both keywords establish a "happens before" relationship between events in different threads.
Whatever some thread A does before it writes a value to some volatile
variable, v
, is guaranteed to be visible to some other thread B after B subsequently reads the same variable, v
.
Whatever some thread A does before it exits from a synchronized(o)
block is guaranteed to be visible to thread B after B subsequently enters a block that is synchronized
on the same object, o
.
Upvotes: 1
Reputation: 7068
Michael's comment is correct. Both approaches are fine.
In terms of performance, it is difficult to say which one is better. It might even depend on the architecture (x86 vs ARM).
The second one might be better for gets, but worse for increments (because both the lock is taken, and a write memory barrier is issued, unless JIT can optimize that away...)
Upvotes: 1