Reputation: 205
I'm trying to use an AtomicInteger variable as lock. So, wondering if the code posted below is thread safe. I know incrementAndGet() is an atomic operation. But, I'm not sure if the subsequent '==' operation will be atomic as well (what if the value gets incremented to 2, by the time I make the comparison.). So posting this question to hear your thoughts.
private AtomicInteger count = new AtomicInteger(0); //Shared variable
private final int max = 1;
if(count.incrementAndGet() == max) {
//Do something
}
Upvotes: 5
Views: 4574
Reputation: 16938
Since incrementAndGet()
is an atomic operation, at most one thread will get 1
for result (as long as the AtomicInteger is not set to a value lower than 1). This is guaranteed by AtomicInteger. Although the actual comparison is not part of this atomic operation, only the thread which received 1
will run into the if
block. That's because the comparison compares two values of type int
: the result of incrementAndGet()
) and max
. The AtomicInteger doesn't play a role in it since the primitive int
doesn't change it's value when the inner state of count
changes. tl;dr: Your code is equivalent to:
final int val = count.incrementAndGet(); // (it makes no difference if val is not 'final`)
if (val == max) {
// ...
}
Java provides many other ways to achieve thread-safety (Lock, CountDownLatch, Semaphore, ...), but since you are referring to an AtomicInteger, I believe AtomicInteger.compareAndSet() is more accurate to what you were asking:
if (count.compareAndSet(0, 1)) {
// executed if count == 0
count.set(0);
}
Upvotes: 6