0

Having read lots about volatile, atomic and visibility, one question remains. Following works across threads, "a" is visible all the time, when "b" is updated/read:

int a;
volatile int b;
a = 1; b = 1;
...
// different thread
if (b == 1) // do something with a, which is 1 now

Does the same hold true with atomic variables, which are separate objects, will the following work?

int a;
AtomicInteger b = new AtomicInteger();
a = 1; b.set(1);
...
// different thread
if (b.get() == 1) // a guaranteed to be 1 here all the time ???

If the answer is no, then it should work to extend the AtomicInteger class and include "a" within there, because AtomicInteger wraps a volatile.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302

3 Answers3

1

A get() is equivalent to reading from a volatile variable, and a set() is equivalent to writing to it. We have a happens-before relationship here write -> read and therefore, "a guaranteed to be 1 here all the time". This of course is in the context of only these two threads executing.

Prashant Pandey
  • 4,332
  • 3
  • 26
  • 44
  • Thanks for the quick answer. What made me nervous, was the fact that the docs call an AtomicInteger a variable, while it is a separate object. But so it works like a volatile variable. I guess this semantics should cause two different cache lines possibly being affected when accessing. Wrapping "a" into an extended Atomic class might reduce this to one. – lockfreecode Apr 21 '21 at 16:04
1

If only the documentation would not specify that explicitly:

Sets the value of a variable to the newValue, with memory semantics of setting as if the variable was declared volatile.

If that is the only code you have that work on that AtomicInteger, then yes, a is guaranteed to be 1.

Eugene
  • 117,005
  • 15
  • 201
  • 306
0

a guaranteed to be 1 here all the time ???

No, other set calls can happen in between.

But then this is also true in the volatile case.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243