Suppose an AtomicInteger,c
, is shared between two threads, thread1 and thread2. Thread1 sets (one time only) a volatile variable t1
using c.incrementAndGet()
. Thread2 sets (one time only) a volatile variable t2
using c.incrementAndGet()
. Once t1 and t2 are set they are not set again by any other thread. Suppose that after thread1 sets t1
, it checks the value of t2
and gets null
. Is it guaranteed that t2
is subsequently set to a higher value then t1
? (and visa versa). In other words are the assert below always true? Is so why?
AtomicInteger c = new AtomicInteger();
volatile Integer t1=null;
volatile Integer t2=null;
//Thread1
t1=c.incrementAndGet();
if(t2 == null){
assert t2==null || t2>t1;
}
//Thread2
t2=c.incrementAndGet();
if(t1==null){
assert t1==null || t1>t2;
}
I believe the asserts are true for the following reason: If t1 is assigned a value from incrementing c and t2 has not yet been assigned a value by incrementing c then when t2 is subsequently assigned a value by incrementing c, it must be greater then the value of t1.
Update: Since as per the correct answer below the asserts may not always hold, I have added a part 2 question: Check out Happens before between threads and atomic variable Part 2.
No, they will not always be true. There is no guarantee that thread 1 will run before thread 2, or that the operations won't interleave. If they run as:
t2 = 1
if
check, which evaluates to truet1 = 2
... then at step 3, thread 2 will see
t1 != null
andt2 > t1
.Thread 1 can similarly fail.
(As JB Nizet mentions, even the operations I wrote above are actually comprised of multiple operations. That level of detail isn't strictly necessary for this question specifically, but it is a good habit to get into to really break things down into their individual operations, like the incrementAndGet vs the assignment it goes into. Experience will let you filter them out a bit when you want to show why something won't work, but to show that it will work, you really do need to consider each operation.)
No, there's no guarantee. The following could happen:
or
is evaluated