Concurrent programming 5 -- atomic operation CAS

Posted by |Adam| on Sun, 02 Feb 2020 16:29:36 +0100


Atom (indivisible)
What is atomic operation? How to implement atomic operation?
syn is based on the blocking lock mechanism. 1. The blocked thread has a high priority. 2. What if the thread that gets the lock does not release the lock all the time? 3. A lot of competition, cpu consumption, and deadlock or other security.
The principle of CAS
CAS(Compare And Swap), the instruction level guarantees that this is an atomic operation
Three operators: A memory address V, an expected value A, A new value B
Basic idea: if the value on address V is equal to the expected value A, assign address V to the new value B. if not, do nothing.
Continuous CAS operation in cycle (dead cycle, spin)

The problem of CAS
A-B-A, version No.: A1B2-A3
CAS operation is not successful for a long time, and cpu keeps cycling,
The use of related atomic operation classes in Jdk
Has AtomicMarkableReference, boolean ever moved
AtomicStampedReference has been moved several times

The code is as follows:

package com;

import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 *
 * When using locks is expensive, you can use atomic operation classes
 */
public class AtomicArray {
    static int[] value = new int[] { 1, 2 };
    
    static AtomicIntegerArray ai = new AtomicIntegerArray(value);
    
    public static void main(String[] args) {
    	ai.getAndSet(0, 3);
    	System.out.println(ai.get(0));
    	System.out.println(value[0]);

    }
}

package com;

import java.util.concurrent.atomic.AtomicInteger;

public class UseAtomicInt {
	
	static AtomicInteger ai = new AtomicInteger(10);
	
    public static void main(String[] args) {
    	System.out.println(ai.getAndIncrement());//10--->11
    	System.out.println(ai.incrementAndGet());//11--->12--->out
    	System.out.println(ai.get());
    }
}

package com;

import java.util.concurrent.atomic.AtomicReference;

/*
 *
 *Class description: demonstrates the atomic operation class of reference type
 */
public class UseAtomicReference {
	
	static AtomicReference<UserInfo> userRef = new AtomicReference<UserInfo>();
	
    public static void main(String[] args) {
        UserInfo user = new UserInfo("Mark", 15);//Instances of entities to modify
        userRef.set(user);
        
        UserInfo updateUser = new UserInfo("Bill", 17);//New examples to change
        userRef.compareAndSet(user, updateUser);
        System.out.println(userRef.get().getName());
        System.out.println(userRef.get().getAge());
        System.out.println(user.getName());
        System.out.println(user.getAge());        
    }
    
    //Define an entity class
    static class UserInfo {
        private String name;
        private int age;
        public UserInfo(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
    }

}

package com;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 *
 *Class description: demonstrates the atomic operation class with version stamp
 */
public class UseAtomicStampedReference {
	
	static AtomicStampedReference<String> asr = 
			new AtomicStampedReference<>("Mark",0);
	

    public static void main(String[] args) throws InterruptedException {
    	final int oldStamp = asr.getStamp();//The original version number
    	final String oldReferenc = asr.getReference();
    	
    	System.out.println(oldReferenc+"==========="+oldStamp);
    	
    	Thread rightStampThread = new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName()
						+"Current variable value:"+oldReferenc+"Current version stamp:"+oldStamp+"-"
						+asr.compareAndSet(oldReferenc, oldReferenc+"Java",
								oldStamp, oldStamp+1));
				
			}
    		
    	});
    	
    	Thread errorStampThread = new Thread(new Runnable() {

			@Override
			public void run() {
				String reference = asr.getReference();
				System.out.println(Thread.currentThread().getName()
						+"Current variable value:"+reference+"Current version stamp:"+asr.getStamp()+"-"
						+asr.compareAndSet(reference, reference+"C",
								oldStamp, oldStamp+1));
				
			}
    		
    	});   	
    	
    	rightStampThread.start();
    	rightStampThread.join();
    	errorStampThread.start();
    	errorStampThread.join();
    	System.out.println(asr.getReference()+"==========="+asr.getStamp());
    	
    }
}

54 original articles published, praised 0, 486 visitors
Private letter follow

Topics: Java JDK