Some understanding of CAS mechanism
Multithreading practice
public class test {
private static int x;
public static void main(String[] args) throws InterruptedException {
Thread task1 = new Thread(){
@Override
public void run(a) {
super.run();
for (int i=0; i<1000; i++){
x=x+1; }}}; Thread task2 =new Thread(){
@Override
public void run(a) {
super.run();
for (int i=0; i<1000; i++){
x=x+1; }}}; task1.start(); task2.start(); task1.join(); task2.join(); System.out.println(x); }/ * * / 1006/ / : ~
Copy the code
Two threads start at the same time, add x, ideally, the output should be 2000, but it ends up being 1006, because if you have multiple threads, you can add two threads at the same time.
public class test {
private static AtomicInteger atomicInteger = new AtomicInteger();
public static void main(String[] args) throws InterruptedException {
Thread task1 = new Thread(){
@Override
public void run(a) {
super.run();
for (int i=0; i<1000; i++){ atomicInteger.incrementAndGet(); }}}; Thread task2 =new Thread(){
@Override
public void run(a) {
super.run();
for (int i=0; i<1000; i++){ atomicInteger.incrementAndGet(); }}}; task1.start(); task2.start(); task1.join(); task2.join(); System.out.println(atomicInteger.get()); }}/ * * / 2000/ / : ~
Copy the code
Modify the accumulated object X to AtomicInteger, resulting in an ideal 2000. Locks are not used in this operation because AtomicInteger introduces the CAS mechanism.
What is the CAS mechanism
The CAS mechanism simply says, compare swap, have expected value, old value and memory location; Take the old value and swap it for the new value.
Why is AtomicInteger thread safe
Source:
private static final longvalueOffset; .public final int incrementAndGet(a) {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }...Unsafe
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
Copy the code
ValueOffset is a hardcoded atomic operation, and incrementAndGet calls unsafe.getAndAddInt, which is implemented using the CAS mechanism. Var5 retrievals the latest current value from the main memory. This value is visible and shared by all threads, swapped with var4, and spins until the update succeeds on failure.
Graphical CAS mechanism
As you can see, CAS is thread safe without using any locks. CAS has many advantages, but also many disadvantages, such as ABA problems
ABA problem
What are ABA problems
Actually, it’s easy to understand, A->B->A, the value of A has not changed, but it has undergone some kind of operation.
The illustration
What effect does it have
Threads 1, 2, and 3 above all do their job without a problem. But if they were transferring money, there was a problem, and $10 was missing from the account.
To solve
Introduce the version number, can solve the problem, every time there is the same value, do a version accumulation, as long as the version number does not match is changed.
conclusion
Advantages: Avoid the consumption disadvantage of locking when concurrency is not very high:
- In the case of high concurrency, if the modification fails for several times, the CPU consumption will continue
- Only atomic level safe changes can be made to variables, not code blocks.