Reputation: 309
Is this class thread-safe?
Is it possible to see inconsistent values? Lets say initially a's value is 80. Thread 1 calls setA(100)
and enters the function but did not yet call a.set(100)
and Thread 2 concurrently calls getA()
. Is it possible for Thread 2 to see 80?
public class A {
private AtomicInteger a;
public int getA() {
return a.get()
}
public void setA(int newVal){
a.set(newVal);
}
}
I know that synchronizing it will guarantee thread 2 sees 100, but not sure with AtomicInteger.
Upvotes: 5
Views: 2884
Reputation: 116306
As @Gray noted, there is a possibility for a race condition here.
Calling get
and then set
is not an atomic operation. The Atomic*
classes offer a lock-free atomic conditional update operation, compareAndSet
- you should use that one for thread safety.
Upvotes: 1
Reputation: 116938
Is this class thread-safe?
Yes it is.
Thread 1 calls setA(100) and enters the function but did not yet call a.set(100) and Thread 2 concurrently calls getA(). Is it possible for Thread 2 to see 80?
Yes. Until the memory barrier code that synchronizes the volatile field inside of AtomicInteger
completes, the race condition can show 80 or 100.
Thread 1 could even enter the AtomicInteger.set
method and be before the inner field assignment and still the 80 may be returned by get AtomicInteger.get
method.
There are no guarantees about when the values will be updated in other threads. What is guaranteed is when the get()
completes, you get the most recent synchronized value and when the set()
completes, all other threads will see the updates.
There is no guarantee as to the timing of getter and setter calls in different threads.
Upvotes: 10