xxtommoxx
xxtommoxx

Reputation: 309

AtomicInteger vs synchronized getters/setters

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

Answers (2)

Péter Török
Péter Török

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

Gray
Gray

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

Related Questions