Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safe negated AtomicBoolean get() as a condition in a while loop

Suppose I have the following code:

AtomicBoolean condition;
condition = new AtomicBoolean(false);
(...)
while(!condition.get()){
   // do some stuff
}

I know that condition.get() is atomic, but, is !condition.get() atomic as well?

I mean, could it happen that one Thread read the boolean value atomically and then it were interrupted before applying the ! operation, so that another Thread gets into the loop before? If that's the case, would it be better to use a function such as:

private synchronized boolean checkNegatedCondition(AtomicBoolean cond){
    return !cond.get();
}

(...)

while(checkNegatedCondition(condition)){
   // do some stuff
}

Thanks in advance.

like image 854
yet_another_programmer Avatar asked Mar 09 '23 08:03

yet_another_programmer


1 Answers

One has to be precise here:

  • the result of the get() operation is supposed to be atomic, and because of the "further" guarantees for any atomic class, it is also guaranteed to be "visible" to other threads looking at the same object (atomic in the sense that all the **set* methods are atomic, so it is not possible to get() something that is "half-set")
  • whereas the ! operation is not protected in any way

And just to be sure: the core thing here is not "atomicity" - because a get() just returns a value (and in contrast to a double, there is even just a single bit/byte affected). In other words: AtomicBoolean is mainly about making sure that changes to the object are visible to all threads using the object.

Buty yes, assuming that AtomicBoolean is a field of a class, and multiple threads are calling a method like:

public void foo() {
  while(!condition.get() ...

it is theoretically possible that

  • Thread A "gets" false
  • Thread B "sets" true
  • Thread A computes computes ! false --> true

But: assume that we had a "protected" getNot(), the final result would be the same:

  • Thread A "getNot" false --> true
  • Thread B "sets" true

In both cases, the first thread would enter the loop!

like image 95
GhostCat Avatar answered Mar 11 '23 02:03

GhostCat