[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Elop1/JavaGuide/master/docs/java/Multithread/Atomic.md [Back]  [Original]

[](#)JavaJava

> 


- [1 Atomic ](#1-atomic-)
- [2 ](#2-)
    - [2.1 ](#21-)
    - [2.2 AtomicInteger ](#22-atomicinteger-)
    - [2.3 ](#23-)
    - [2.4 AtomicInteger ](#24-atomicinteger-)
- [3 ](#3-)
    - [3.1 ](#31-)
    - [3.2 AtomicIntegerArray ](#32-atomicintegerarray-)
- [4 ](#4-)
    - [4.1  ](#41--)
    - [4.2 AtomicReference ](#42-atomicreference-)
    - [4.3 AtomicStampedReference ](#43-atomicstampedreference-)
    - [4.4 AtomicMarkableReference ](#44-atomicmarkablereference-)
- [5 ](#5-)
    - [5.1 ](#51-)
    - [5.2 AtomicIntegerFieldUpdater ](#52-atomicintegerfieldupdater-)


### 1 Atomic 

Atomic  Atomic 

/

 `java.util.concurrent` `java.util.concurrent.atomic`,

![JUC](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/JUC.png)

JUC4

**** 



- AtomicInteger
- AtomicLong
-  AtomicBoolean 

****




- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray 

****

- AtomicReference
- AtomicMarkableReference boolean ~~ CAS  ABA ~~
- AtomicStampedReference  CAS  ABA 

****

- AtomicIntegerFieldUpdater:
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater

> : **AtomicMarkableReference ABA**   **[issue#626](https://github.com/Snailclimb/JavaGuide/issues/626)**

```java
    /**

AtomicMarkableReferencebooleantruefalse

ABAABA

@author : mazh

@Date : 2020/1/17 14:41
*/

public class SolveABAByAtomicMarkableReference {
       
       private static AtomicMarkableReference atomicMarkableReference = new AtomicMarkableReference(100, false);

        public static void main(String[] args) {

            Thread refT1 = new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                atomicMarkableReference.compareAndSet(100, 101, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
                atomicMarkableReference.compareAndSet(101, 100, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
            });

            Thread refT2 = new Thread(() -> {
                boolean marked = atomicMarkableReference.isMarked();
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean c3 = atomicMarkableReference.compareAndSet(100, 101, marked, !marked);
                System.out.println(c3); // true,false
            });

            refT1.start();
            refT2.start();
        }
    }
```

**CAS ABA **
- :  x  A x  A x  A x  B x  A  x  x  A compareAndSet 
- (): 
- ``` AtomicInteger ```

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

public class AtomicIntegerDefectDemo {
    public static void main(String[] args) {
        defectOfABA();
    }

    static void defectOfABA() {
        final AtomicInteger atomicInteger = new AtomicInteger(1);

        Thread coreThread = new Thread(
                () -> {
                    final int currentValue = atomicInteger.get();
                    System.out.println(Thread.currentThread().getName() + " ------ currentValue=" + currentValue);

                    // 
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    boolean casResult = atomicInteger.compareAndSet(1, 2);
                    System.out.println(Thread.currentThread().getName()
                            + " ------ currentValue=" + currentValue
                            + ", finalValue=" + atomicInteger.get()
                            + ", compareAndSet Result=" + casResult);
                }
        );
        coreThread.start();

        //  coreThread 
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread amateurThread = new Thread(
                () -> {
                    int currentValue = atomicInteger.get();
                    boolean casResult = atomicInteger.compareAndSet(1, 2);
                    System.out.println(Thread.currentThread().getName()
                            + " ------ currentValue=" + currentValue
                            + ", finalValue=" + atomicInteger.get()
                            + ", compareAndSet Result=" + casResult);

                    currentValue = atomicInteger.get();
                    casResult = atomicInteger.compareAndSet(2, 1);
                    System.out.println(Thread.currentThread().getName()
                            + " ------ currentValue=" + currentValue
                            + ", finalValue=" + atomicInteger.get()
                            + ", compareAndSet Result=" + casResult);
                }
        );
        amateurThread.start();
    }
}
```



```
Thread-0 ------ currentValue=1
Thread-1 ------ currentValue=1, finalValue=2, compareAndSet Result=true
Thread-1 ------ currentValue=2, finalValue=1, compareAndSet Result=true
Thread-0 ------ currentValue=1, finalValue=2, compareAndSet Result=true
```



### 2 

#### 2.1 



- AtomicInteger
- AtomicLong
-  AtomicBoolean 

 AtomicInteger 

 **AtomicInteger **

```java
public final int get() //
public final int getAndSet(int newValue)//
public final int getAndIncrement()//
public final int getAndDecrement() //
public final int getAndAdd(int delta) //
boolean compareAndSet(int expect, int update) //update
public final void lazySet(int newValue)//newValue, lazySet 
```

#### 2.2 AtomicInteger 

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

public class AtomicIntegerTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int temvalue = 0;
		AtomicInteger i = new AtomicInteger(0);
		temvalue = i.getAndSet(3);
		System.out.println("temvalue:" + temvalue + ";  i:" + i);//temvalue:0;  i:3
		temvalue = i.getAndIncrement();
		System.out.println("temvalue:" + temvalue + ";  i:" + i);//temvalue:3;  i:4
		temvalue = i.getAndAdd(5);
		System.out.println("temvalue:" + temvalue + ";  i:" + i);//temvalue:4;  i:9
	}

}
```

#### 2.3 



****

```java
class Test {
        private volatile int count = 0;
        //count++
        public synchronized void increment() {
                  count++; 
        }

        public int getCount() {
                  return count;
        }
}
```
****

```java
class Test2 {
        private AtomicInteger count = new AtomicInteger();

        public void increment() {
                  count.incrementAndGet();
        }
      //AtomicInteger
       public int getCount() {
                return count.get();
        }
}

```
#### 2.4 AtomicInteger 

AtomicInteger 

```java
    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;
```

AtomicInteger  CAS (compare and swap) + volatile  native  synchronized 

CASUnSafe  objectFieldOffset()  value volatile JVM 


### 3 

#### 3.1 




- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray 

 AtomicIntegerArray 

**AtomicIntegerArray **

```java
public final int get(int i) // index=i 
public final int getAndSet(int i, int newValue)// index=i newValue
public final int getAndIncrement(int i)// index=i 
public final int getAndDecrement(int i) // index=i 
public final int getAndAdd(int i, int delta) // index=i 
boolean compareAndSet(int i, int expect, int update) // index=i update
public final void lazySet(int i, int newValue)// index=i newValue, lazySet 
```
#### 3.2 AtomicIntegerArray 

```java

import java.util.concurrent.atomic.AtomicIntegerArray;

public class AtomicIntegerArrayTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int temvalue = 0;
		int[] nums = { 1, 2, 3, 4, 5, 6 };
		AtomicIntegerArray i = new AtomicIntegerArray(nums);
		for (int j = 0; j < nums.length; j++) {
			System.out.println(i.get(j));
		}
		temvalue = i.getAndSet(0, 2);
		System.out.println("temvalue:" + temvalue + ";  i:" + i);
		temvalue = i.getAndIncrement(0);
		System.out.println("temvalue:" + temvalue + ";  i:" + i);
		temvalue = i.getAndAdd(0, 5);
		System.out.println("temvalue:" + temvalue + ";  i:" + i);
	}

}
```

### 4 

#### 4.1  

 

- AtomicReference
- AtomicStampedReference CAS  ABA 
- AtomicMarkableReference  boolean ~~ CAS  ABA ~~

 AtomicReference 

#### 4.2 AtomicReference 

```java
import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceTest {

	public static void main(String[] args) {
		AtomicReference ar = new AtomicReference();
		Person person = new Person("SnailClimb", 22);
		ar.set(person);
		Person updatePerson = new Person("Daisy", 20);
		ar.compareAndSet(person, updatePerson);

		System.out.println(ar.get().getName());
		System.out.println(ar.get().getAge());
	}
}

class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}
```
 Person  Person  AtomicReference  compareAndSet  CAS  ar ar  person  updatePerson AtomicInteger  compareAndSet 

```
Daisy
20
```
#### 4.3 AtomicStampedReference 

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

public class AtomicStampedReferenceDemo {
    public static void main(String[] args) {
        //  stamp 
        final Integer initialRef = 0, initialStamp = 0;
        final AtomicStampedReference asr = new AtomicStampedReference(initialRef, initialStamp);
        System.out.println("currentValue=" + asr.getReference() + ", currentStamp=" + asr.getStamp());

        // compare and set
        final Integer newReference = 666, newStamp = 999;
        final boolean casResult = asr.compareAndSet(initialRef, newReference, initialStamp, newStamp);
        System.out.println("currentValue=" + asr.getReference()
                + ", currentStamp=" + asr.getStamp()
                + ", casResult=" + casResult);

        //  stamp 
        int[] arr = new int[1];
        final Integer currentValue = asr.get(arr);
        final int currentStamp = arr[0];
        System.out.println("currentValue=" + currentValue + ", currentStamp=" + currentStamp);

        //  stamp 
        final boolean attemptStampResult = asr.attemptStamp(newReference, 88);
        System.out.println("currentValue=" + asr.getReference()
                + ", currentStamp=" + asr.getStamp()
                + ", attemptStampResult=" + attemptStampResult);

        //  stamp 
        asr.set(initialRef, initialStamp);
        System.out.println("currentValue=" + asr.getReference() + ", currentStamp=" + asr.getStamp());

        // [] weak compare and set
        // weakCompareAndSet  compareAndSet [: jdk-8u191]
        //  "May fail spuriously and does not provide ordering guarantees,
        // so is only rarely an appropriate alternative to compareAndSet."
        // todo  jvm  native 
        final boolean wCasResult = asr.weakCompareAndSet(initialRef, newReference, initialStamp, newStamp);
        System.out.println("currentValue=" + asr.getReference()
                + ", currentStamp=" + asr.getStamp()
                + ", wCasResult=" + wCasResult);
    }
}
```


```
currentValue=0, currentStamp=0
currentValue=666, currentStamp=999, casResult=true
currentValue=666, currentStamp=999
currentValue=666, currentStamp=88, attemptStampResult=true
currentValue=0, currentStamp=0
currentValue=666, currentStamp=999, wCasResult=true
```

#### 4.4 AtomicMarkableReference 

``` java
import java.util.concurrent.atomic.AtomicMarkableReference;

public class AtomicMarkableReferenceDemo {
    public static void main(String[] args) {
        //  mark 
        final Boolean initialRef = null, initialMark = false;
        final AtomicMarkableReference amr = new AtomicMarkableReference(initialRef, initialMark);
        System.out.println("currentValue=" + amr.getReference() + ", currentMark=" + amr.isMarked());

        // compare and set
        final Boolean newReference1 = true, newMark1 = true;
        final boolean casResult = amr.compareAndSet(initialRef, newReference1, initialMark, newMark1);
        System.out.println("currentValue=" + amr.getReference()
                + ", currentMark=" + amr.isMarked()
                + ", casResult=" + casResult);

        //  mark 
        boolean[] arr = new boolean[1];
        final Boolean currentValue = amr.get(arr);
        final boolean currentMark = arr[0];
        System.out.println("currentValue=" + currentValue + ", currentMark=" + currentMark);

        //  mark 
        final boolean attemptMarkResult = amr.attemptMark(newReference1, false);
        System.out.println("currentValue=" + amr.getReference()
                + ", currentMark=" + amr.isMarked()
                + ", attemptMarkResult=" + attemptMarkResult);

        //  mark 
        amr.set(initialRef, initialMark);
        System.out.println("currentValue=" + amr.getReference() + ", currentMark=" + amr.isMarked());

        // [] weak compare and set
        // weakCompareAndSet  compareAndSet [: jdk-8u191]
        //  "May fail spuriously and does not provide ordering guarantees,
        // so is only rarely an appropriate alternative to compareAndSet."
        // todo  jvm  native 
        final boolean wCasResult = amr.weakCompareAndSet(initialRef, newReference1, initialMark, newMark1);
        System.out.println("currentValue=" + amr.getReference()
                + ", currentMark=" + amr.isMarked()
                + ", wCasResult=" + wCasResult);
    }
}
```


```
currentValue=null, currentMark=false
currentValue=true, currentMark=true, casResult=true
currentValue=true, currentMark=true
currentValue=true, currentMark=false, attemptMarkResult=true
currentValue=null, currentMark=false
currentValue=true, currentMark=true, wCasResult=true
```

### 5 

#### 5.1 



- AtomicIntegerFieldUpdater:
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater 

 newUpdater() public volatile 

 `AtomicIntegerFieldUpdater`

#### 5.2 AtomicIntegerFieldUpdater 

```java
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntegerFieldUpdaterTest {
	public static void main(String[] args) {
		AtomicIntegerFieldUpdater a = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");

		User user = new User("Java", 22);
		System.out.println(a.getAndIncrement(user));// 22
		System.out.println(a.get(user));// 23
	}
}

class User {
	private String name;
	public volatile int age;

	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}
```



```
22
23
```

## Reference

- Java

## 



**Java:** JavaV2.0 PDF [](#) **""** 

**Java:** Java **1**  

![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png)

Web Proxy Viewer  |  New URL  |  Original Page