Concurrent programming operation of atoms Atomic & Unsafe

Atomic operations: 507,383,170 can not be split (interrupted) or of a series of operations is called an atomic operation.

Atomic atomic operation 12 main categories, four types of atomic update mode, update the basic types of atoms, atomic update array, field updates atoms, atomic update reference. Atomic package wrapper classes are basically used Unsafe implemented.

Basic types: AtomicInteger, AtomicLong, AtomicBoolean;

Reference types: AtomicReference, ABA examples of AtomicReference, AtomicStampedRerence, AtomicMarkableReference;

Array type: AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray;

Attribute atom modifier (Updater): AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater;

1, the basic atomic update typeclasses

  By means for updating the basic types of atoms, Atomic package provides the following three categories: AtomicBoolean: Boolean atomic update. AtomicInteger: atomic updates integer. AtomicLong: atomic update long integer. AtomicInteger common methods are as follows: int addAndGet (int delta): Numerical Example Atomically input value (in the AtomicInteger value) are added, and returns the result boolean compareAndSet (int expect, int update): if the input value is equal to the value of atomically set the value of the input value. int getAndIncrement (): Atomically current value plus 1, Note: this is the value returned from the front. void lazySet (int newValue): eventually set newValue, after use lazySet settings may cause other threads within a short time after can still read the old value. int getAndSet (int newValue): atomically newValue set to a value of, and return values. Atomic package provides three basic types of atoms update, but there are still basic types of Java char, fldouble and so on. So the question is, how to update other basic types of atoms it? Atomic bag Unsafe implemented using basic classes, only three Unsafe CAS method, compareAndSwapObject, compareAndSwapInt and compareAndSwapLong, look AtomicBoolean source, convert to integer Boolean found first, then use compareAndSwapInt for CAS, so atomic update dou It can also be achieved with similar ideas.

Here we look at an example of each type:

Copy the code
/**  
* <p>Title: AtomicIntegerTest.java</p >  
* <p>Description: </p >  
* <p>Copyright: NTT DATA Synergy All Rights Reserved.</p >  
* <p>Company: www.synesoft.com.cn</p >  
* <p>@datetime 2019年8月9日 上午8:01:30</p >
* <p>$Revision$</p > 
* <p>$Date$</p >
* <p>$Id$</p >
*/  
package com.test;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author hong_liping
 *
 */
public class AtomicIntegerTest {
    static AtomicInteger ai=new AtomicInteger();
    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(new Runnable() {
                
                @Override 
                public void RUN () { 
                    ai.incrementAndGet (); 
                    
                } 
            .}) Start (); 
        } 
// the try { 
// the Thread.sleep (100); 
//} the catch (InterruptedException E) { 
// e.printStackTrace (); 
//} 
        System.out.println ( "result of the following cycle:" + ai.get ()); 
    } 

} 
// test results
rotation result is as follows: 9
results after cycles were as follows: 10
Copy the code

According to the above code, we run more than a few times, you will find the test results for a moment while the code is 9 is 10, not 10, why, because the thread has not finish, I had the following play out, let the thread sleep We can solve this problem.

Here we look at atomic the ABA problem, the problem during the interview often asked.

Copy the code
/**  
* <p>Title: AtomicTest.java</p >  
* <p>Description: </p >  
* <p>@datetime 2019年8月8日 下午3:40:37</p >
* <p>$Revision$</p > 
* <p>$Date$</p >
* <p>$Id$</p >
*/  
package com.test;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author hong_liping
 *
 */
public class AtomicAbaTest {
     private static AtomicInteger ato=new AtomicInteger(1);
    public static void main(String[] args) {
        Thread mainT=new Thread(new Runnable() {
            
            @Override
            public void run() {
                int a=ato.get();
                System.out.println(Thread.currentThread().getName()+"原子操作修改前数据"+a);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean successFlag=ato.compareAndSet(a, 2);
                if(successFlag){
                    System.out.println(Thread.currentThread().getName()+"原子操作修改后数据"+ato.get());
                }
                
            }
        },"mainT");
        
        Thread otherT=new Thread(new Runnable() {
            
            @Override
            public void run() {
                int b=ato.incrementAndGet();//1+1
                System.out.println (. Thread.currentThread () getName ( ) + " atomic increment operation after the data" B +); 
                 B = ato.decrementAndGet (); // 2-1 
                System.out.println (Thread.currentThread () .getName () + "Save atomic operation since the data" B +);                 
            } 
        }, "OtherT"); 
        
        mainT.start (); 
        otherT.start (); 
    } 

} 

test results:

After OtherT 2 atomic increment data
MAINT atomic operation before modification data 1
OtherT atomic decrement data after a
post-atomic operation to modify the data MAINT 2

 
Copy the code

According to the above operation, we can see that the operation AtomicInteger increment, decrement, etc. Alternatively value. Here it should be noted that there is a problem atomic operation ABA, ABA problem is that the phenomenon of: performing value after completion mainT 2 (alternative 2), otherT 2-1 when executed is incremented to 2 (1 + 1 )the result of. Used in these two threads 2 is not the same 2, the equivalent of a loophole, the equivalent of saying you stole 10 million account from Wang Jianlin to invest in, so you better back this investment, and then you this 10 million dozen back to Wang Jianlin account, this whole process did not find Wang Jianlin, you did not record the whole operation, so for Wang Jianlin, who had not lost his money, or put there. When it is clear that the best way to solve this problem is the ABA every step of the operation are to make a mark, the equivalent of a bank of water, so you steal money, pay back the money out of the whole process there is a one in, just to see Wang Jianlin I find that the total gold has not changed, but the operating records show that my money had been stolen by the people and then come back up. That's where AtomicStampeReference.

2, reference type atomic update

Atomic update basic types of AtomicInteger, can only update a variable, if you want to update multiple variables atoms, atomic updates you need to use this class reference type provided. Atomic package provides the following three categories: AtomicReference: atomic update reference type. AtomicReferenceFieldUpdater: atomic update reference types in the field. AtomicMarkableReference: update the reference type atom marked position. Atoms can update a boolean flag and reference types. Constructor is AtomicMarkableReference (V initialRef, boolean initialMark)

Next we look at AtomicStampedReference test class:

Copy the code
/**  
* <p>Title: AtomicStampedReference.java</p >  
* <p>Description: </p >  
* <p>@datetime 2019年8月9日 上午8:35:56</p >
* <p>$Revision$</p > 
* <p>$Date$</p >
* <p>$Id$</p >
*/  
package com.test;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author hong_liping
 *
 */
public class AtomicStampedReferenceTest {

     private static AtomicStampedReference<Integer> asf=new AtomicStampedReference<Integer>(1, 0);
    public static void main(String[] args) {
        Thread mainT=new Thread(new Runnable() {
            
            @Override
            RUN void public () { 
                int = asf.getStamp Stamp (); 
                . System.out.println (Thread.currentThread () getName () + "atomic data before modification" asf.getReference + () + 
                        "_" + Stamp ); 
                the try { 
                    the Thread.sleep (1000); 
                } the catch (InterruptedException E) { 
                    e.printStackTrace (); 
                } 
                // At this point expectedReference not changed, but the stamp has been modified, so CAS failure 
                boolean successFlag = asf.compareAndSet (. 1, 2, Stamp, Stamp +. 1); 
                IF (successFlag) { 
                    . System.out.println (Thread.currentThread () getName () + "the atomic modified data" + asf.getReference () + 
                            "_" + Stamp); 
                } the else {
                    System.out.println(Thread.currentThread().getName()+"cas操作失败");
                }
                
            }
        },"mainT");
        
        Thread otherT=new Thread(new Runnable() {
            
            @Override
            public void run() {
                int stamp=asf.getStamp();
                asf.compareAndSet(1, 2, stamp, stamp+1);
                System.out.println(Thread.currentThread().getName()+"原子操作自增后数据"+asf.getReference()+
                        "_"+asf.getReference());
                
                asf.compareAndSet(2, 1, stamp, stamp+1);                
                System.out.println (. Thread.currentThread () getName ( ) + " Save the data from the atomic operation" asf.getReference + () +
                        "_"+stamp);;                
            }
        }, "OtherT"); 
        
        mainT.start (); 
        otherT.start (); 
    } 



} 
// test results: 
MAINT atomic operation before modification data 2_0 
OtherT atomic increment operation after data 2_2 
OtherT Save the data from the atomic 2_0 
mainTcas operation failed
Copy the code
3, the array type atomic update
  Update an element of array by way atoms, Atomic package provides the following three categories AtomicIntegerArray: atomic update integer array elements. AtomicLongArray: atomic update long integer array elements. AtomicReferenceArray: atomic update reference type array elements. omicIntegerArray principal embodiment provided is updated array integer atoms in its usual method int addAndGet (int i, int delta): Atomically Mississauga input value array. boolean compareAndSet (int i, int expect, int update): If the value Atomically the elements of the array at position i is set to update the value.

Next we look at a case of AtomicIntegerArray

Copy the code
/**  
* <p>Title: AtomicArrayTest.java</p >  
* <p>Description: </p >  
* <p>@datetime 2019年8月10日 上午9:45:49</p >
* <p>$Revision$</p > 
* <p>$Date$</p >
* <p>$Id$</p >
*/  
package com.test;

import java.util.concurrent.atomic.AtomicIntegerArray;

import com.sun.org.apache.bcel.internal.generic.NEWARRAY;

/**
 * @author hong_liping
 *
 */
public class AtomicArrayTest {
    static int[] array=new int[]{1,2,3};
    static AtomicIntegerArray aia=new AtomicIntegerArray(array);
    public static void main(String[] args) {
        aia.getAndSet(1, 5);
        System.out.println(aia.get(1));
        System.out.println (Array [. 1]);
        IF (aia.get (. 1) == Array [. 1]) { 
            System.out.println ( "value of the atomic array in the array is equal to"); 
        } the else { 
            System.out.println ( "values in the array atoms and not equal to the array "); 
        } 
    } 

} 
results:

. 5
2
is not equal to the values in the array of arrays atoms in

 
Copy the code

The code can be seen from the above atomic array with the same value index I defined data itself is not the same, and why, we look at the data source you will find not atomic operation I define the variable itself, It is the first copy, and then the operation is a copy version.

Copy the code
AtomicIntegerArray public (int [] Array) { 
        // the Visibility Guaranteed by Final Field Guarantees 
        this.array array.clone = (); // array initialization time copying 
    }
public final int getAndSet(int i, int newValue) {
        return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);
    }
 
 
Copy the code

Atomic operation used when performing data type magic Unsafe.

4, atomic update field class

If we only need a class in a field, then you need to use atomic updates field class, Atomic mention package
For the following three categories:
AtomicIntegerFieldUpdater: atomic update updater integer field.
AtomicLongFieldUpdater: atomic update updater long integer field.
AtomicStampedReference: atomic update version number with a reference type. Such an integer value
More data and the version number associated with the reference data it can be used for the atom, can be solved using atomic CAS
When updating, ABA issues that may arise. Atomic update field classes are abstract classes, each use must be used when creating a static method newUpdater
Updater. Field atomic update must use the public volatile type modifier.

Next we look at AtomicIngerFieldUpdater

Copy the code
/**  
* <p>Title: AtomicIntegerFieldUpdateTest.java</p >  
* <p>Description: </p >    
* <p>@datetime 2019年8月10日 上午10:02:22</p >
* <p>$Revision$</p > 
* <p>$Date$</p >
* <p>$Id$</p >
*/  
package com.test;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * @author hong_liping
 *
 */
public class AtomicIntegerFieldUpdateTest {
    static AtomicIntegerFieldUpdater aifu=AtomicIntegerFieldUpdater.newUpdater(Person.class, "age");

    static class Person{
        private String name;
        public volatile int age;
      public Person(String name,int age){
          this.name=name;
          this.age=age;
      }
      public  int getAge(){
          return age;
 

Guess you like

Origin www.cnblogs.com/aa1122/p/11706155.html