2

Say I have a class with 2 instance variables and the following methods (simplified for this question):

private final Object lock = new Object();
private boolean running;

public MyClass() {
    synchronized(lock) {
        running = false;
    }
}
public void methodA() {
    synchronized(lock) {
        running = true;
    }
}
public void methodB() {
    synchronized(lock) {
        if (!running) {
            return;
        }
    }
}

I was looking at this code, and after reading about AtomicBoolean, I thought that one might fit here, especially after looking at the MyClass constructor and methodA. I wasn't too sure about methodB though.

Assuming these methods could get called by multiple threads, would the following be thread-safe?:

private AtomicBoolean running;

public MyClass() {
    running = new AtomicBoolean(false);
}
public void methodA() {
    running.set(true);
}
public void methodB() {
    if (!running.get()) {
        return;
    }
}

Will running.get() be guaranteed to see an update via running.set(true) or running.set(false) from another thread?

Evan LaHurd
  • 977
  • 2
  • 14
  • 27

3 Answers3

2

In your example, a simple volatile boolean would be enough, since you only seem to be doing atomic operations. AtomicBoolean is useful if you need the methods such as compareAndSet.

So in answer to your question, yes, when using a volatile boolean or an AtomicBoolean, other threads will see the updates to the variable.

Valette_Renoux
  • 366
  • 1
  • 9
  • I am not so sure. If there are multiple readers and _one_ writer, then perhaps _volatile_ guarantees are enough. But the moment there are multiple writers, I am not sure if use of _volatile_ is guaranteed. – Kedar Mhaswade Mar 07 '16 at 19:11
  • 3
    Look at the source for AtomicBoolean - it is basically a volatile boolean in an object, if you don't use the compareAndSet methods. Multiple writers are not a problem, in either case. – Valette_Renoux Mar 07 '16 at 19:14
  • According to [this](http://tutorials.jenkov.com/java-concurrency/volatile.html) (not sure how accurate it is), apparently it is okay if there are multiple writers as long as the new written values don't depend on the previous value, but as soon as you need to check the previous value then set a new one based on the previous one, then `volatile` is not enough. – Evan LaHurd Mar 07 '16 at 19:17
  • Exactly: this is when you need methods such as compareAndSet (you do the affectation depending on the previous value) – Valette_Renoux Mar 07 '16 at 19:20
  • Agree, in this case, the use of `AtomicBoolean` is equivalent to use of `volatile boolean`. – Kedar Mhaswade Mar 07 '16 at 19:41
  • @KedarMhaswade, Equivalent in function, but using `AtomicBoolean` is more of a modern style. Style is important if you're collaborating with other developers. The more you can make your code look like theirs, the more willing they will be to read it, comment on it, etc. – Solomon Slow Mar 07 '16 at 19:54
  • I disagree. AtomicBoolean introduces cumbersome "get" and "set" calls instead of normal read and write. Also, you can have concurrency on variables other than boolean or integer. It is important to understand the meaning of volatile and to use it correctly. – Valette_Renoux Mar 07 '16 at 20:10
1

Generally speaking these code blocks are not equal for methodB, because reading volatile variable does not create synchronization order.

Imagine you have some other field int x = 42 in your class, that is updated in methodB:

public void methodB() {
    if (!running.get()) {
        return;
    }
    if (x < 50) x++; // just example
}

Then you have several threads that call methodB:

  • when using synchronized keyword, updates are safe and visible to all threads.
  • when using AtomicBoolean/volatile visibility is broken

If there is no such case with variable updates and the task is just to guarantee visibility between methodA - methodB sequence, then it's OK - AtomicBoolean is enough for that.

AdamSkywalker
  • 11,408
  • 3
  • 38
  • 76
0

Yes. From the Javadoc of AtomicBoolean:

A {@code boolean} value that may be updated atomically.

This means that any update to AtomicBoolean is indivisible. So, I would consider such use of AtomicBoolean to be thread safe.

You should still consider making the declaration of AtomicBoolean final:

private final AtomicBoolean running;

Kedar Mhaswade
  • 4,535
  • 2
  • 25
  • 34
  • 2
    Any update to any `boolean` variable is indivisible. The `AtomicXxxxxxx` classes buy you two things: (a) They give you `volatile`-like access to the primitive value, and (b) they give you lock-free implementations of `getAndSet()`, `compareAndSet()`, `incrementAndGet()`, etc. – Solomon Slow Mar 07 '16 at 19:59