[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/backdiy/JavaGuide/main/docs/java/concurrent/atomic-classes.md [Back]  [Original]

---
title:  Atomic 
category: Java
tag:
  - Java
---


## 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)

 JUC  4 

****



- AtomicInteger
- AtomicLong
- AtomicBoolean 

****



- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray 

****

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

****

- AtomicIntegerFieldUpdater:
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater

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

```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
```



## 

### 



- 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 
```

### 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
	}

}
```

### 



** **

```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();
        }
}

```

### 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 

CAS UnSafe  objectFieldOffset()  value  volatile  JVM 

## 

### 



- 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 
```

### 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);
	}

}
```

## 

### 

 

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

 AtomicReference 

### 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
```

### 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
```

### 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
```

## 

### 



- AtomicIntegerFieldUpdater:
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater 

 newUpdater() public volatile 

 `AtomicIntegerFieldUpdater`

### 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 

Web Proxy Viewer  |  New URL  |  Original Page