public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
This is an auto-increment operation, definition: CAS has 3 operands, memory value V, old expected value A, and new value to be modified B. If and only if the expected value A and the memory value V are the same, modify the memory value V to B, otherwise do nothing
Is the expected value next? The memory value is current?
If there is no competition from other threads when a thread is incremented, then the expected value should be 1 greater than the memory value. How come the expected value and the memory value are the same?
Laxative~
Maybe the author’s understanding of the question is a bit wrong
current is the expected value, not the memory value
next is the modified new value, not the expected value
method
compareAndSet
can be seen, and the comments inside are very clearThe operation of CAS is as mentioned by the questioner. It compares the expected value with the memory value. Only when they are equal, the new value will be written. Otherwise, it will keep retrying. This is an optimistic attitude, and the real memory value In fact, it is the attribute
AtomicInteger.value
(actually the most important thing is not this attribute, it is just a reference, the real boss will mention it later). Note that this value is modified by the keywordvolatile
So this value is actually a shared variable, which represents the visibility of this variable, that is, the visibility between threads,
======================== I’m just talking too much about visibility, if you don’t like it you can just skip it =========== =====================
To put it simply, the Java memory model stipulates that variables are stored in main memory (similar to physical memory). Each thread has its own work cache. When operating on a variable, the value in the main memory is not directly modified, but It is executed in its own work cache, and finally synchronized to the main memory, and threads cannot access each other's work cache
The visibility mentioned here means that when a thread operates a variable modified with the keyword
volatile
, when the variable is successfully modified and written to the main memory, the variables in the work cache of other threads will become invalid. So at this time, when other threads read the variable again, they will read it directly from the main memory instead of using the value in their own working cache==========================================Finished====== =========================================
I just mentioned that the
AtomicInteger.value
attribute is just a reference to the data itself. When calling thecompareAndSet
method, you can notice the second parameter,valueOffset
. In fact, this is the key... Really Boss, the real memory value, because it involves a word rarely heard in the Java language, pointer, thisvalueOffset
is actually the offset within the object, this is the real memory value(The reason why this method
compareAndSet
calls the method ofUnsafe
class,Unsafe
actually encapsulates some pointer-like operations, pointers are not safe)