Reputation: 1182
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.
Upvotes: 2
Views: 203
Reputation: 43456
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
and t2 > 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.)
Upvotes: 1
Reputation: 692231
No, there's no guarantee. The following could happen:
or
is evaluatedUpvotes: 1