5

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
}
steffen
  • 16,138
  • 4
  • 42
  • 81
V1666
  • 185
  • 3
  • 14

1 Answers1

6

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);
}
steffen
  • 16,138
  • 4
  • 42
  • 81
  • 1
    Much more clear now. I want only one thread to execute some functionality. Hence, I'm checking for the count. Since, its guaranteed that only one thread will see a value of 1, I can safely expect the logic residing within the 'if' condition to be thread-safe. As every operation of incrementandGet() will increase the count, there will only be one thread reading a value of 1. So, that answers my question. Thanks steffen. – V1666 Sep 21 '18 at 18:30