---
title: Atomic ååç±»æ»ç»
category: Java
tag:
- Javaå¹¶å
---
## Atomic ååç±»ä»ç»
Atomic ç¿»è¯æä¸ææ¯ååçææãå¨åå¦ä¸ï¼æä»¬ç¥éå忝ææä¸è¬ç©è´¨çæå°åä½ï¼å¨åå¦ååºä¸æ¯ä¸å¯åå²çã卿们è¿é Atomic æ¯æä¸ä¸ªæä½æ¯ä¸å¯ä¸æçãå³ä½¿æ¯å¨å¤ä¸ªçº¿ç¨ä¸èµ·æ§è¡çæ¶åï¼ä¸ä¸ªæä½ä¸æ¦å¼å§ï¼å°±ä¸ä¼è¢«å
¶ä»çº¿ç¨å¹²æ°ã
æä»¥ï¼æè°åå类说ç®åç¹å°±æ¯å
·æåå/ååæä½ç¹å¾çç±»ã
å¹¶åå
`java.util.concurrent` çååç±»é½åæ¾å¨`java.util.concurrent.atomic`ä¸,å¦ä¸å¾æç¤ºã

æ ¹æ®æä½çæ°æ®ç±»åï¼å¯ä»¥å° JUC å
ä¸çååç±»å为 4 ç±»
**åºæ¬ç±»å**
使ç¨ååçæ¹å¼æ´æ°åºæ¬ç±»å
- `AtomicInteger`ï¼æ´åååç±»
- `AtomicLong`ï¼é¿æ´åååç±»
- `AtomicBoolean`ï¼å¸å°åååç±»
**æ°ç»ç±»å**
使ç¨ååçæ¹å¼æ´æ°æ°ç»éçæä¸ªå
ç´
- `AtomicIntegerArray`ï¼æ´åæ°ç»ååç±»
- `AtomicLongArray`ï¼é¿æ´åæ°ç»ååç±»
- `AtomicReferenceArray`ï¼å¼ç¨ç±»åæ°ç»ååç±»
**å¼ç¨ç±»å**
- `AtomicReference`ï¼å¼ç¨ç±»åååç±»
- `AtomicMarkableReference`ï¼ååæ´æ°å¸¦ææ è®°çå¼ç¨ç±»åãè¯¥ç±»å° boolean æ è®°ä¸å¼ç¨å
³èèµ·æ¥ï¼~~ä¹å¯ä»¥è§£å³ä½¿ç¨ CAS è¿è¡ååæ´æ°æ¶å¯è½åºç°ç ABA é®é¢~~ã
- `AtomicStampedReference`ï¼ååæ´æ°å¸¦æçæ¬å·çå¼ç¨ç±»åãè¯¥ç±»å°æ´æ°å¼ä¸å¼ç¨å
³èèµ·æ¥ï¼å¯ç¨äºè§£å³ååçæ´æ°æ°æ®åæ°æ®ççæ¬å·ï¼å¯ä»¥è§£å³ä½¿ç¨ CAS è¿è¡ååæ´æ°æ¶å¯è½åºç°ç ABA é®é¢ã
**ð ä¿®æ£ï¼åè§ï¼[issue#626](https://github.com/Snailclimb/JavaGuide/issues/626)ï¼** : `AtomicMarkableReference` ä¸è½è§£å³ ABA é®é¢ã
**对象ç屿§ä¿®æ¹ç±»å**
- `AtomicIntegerFieldUpdater`:ååæ´æ°æ´ååæ®µçæ´æ°å¨
- `AtomicLongFieldUpdater`ï¼ååæ´æ°é¿æ´ååæ®µçæ´æ°å¨
- `AtomicReferenceFieldUpdater`ï¼ååæ´æ°å¼ç¨ç±»åéçåæ®µ
## åºæ¬ç±»åååç±»
使ç¨ååçæ¹å¼æ´æ°åºæ¬ç±»å
- `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) {
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
}
}
```
### åºæ¬æ°æ®ç±»åååç±»çä¼å¿
éè¿ä¸ä¸ªç®åä¾å带大家çä¸ä¸åºæ¬æ°æ®ç±»åååç±»çä¼å¿
**1ãå¤çº¿ç¨ç¯å¢ä¸ä½¿ç¨ååç±»ä¿è¯çº¿ç¨å®å
¨ï¼åºæ¬æ°æ®ç±»åï¼**
```java
class Test {
private volatile int count = 0;
//è¥è¦çº¿ç¨å®å
¨æ§è¡æ§è¡count++ï¼éè¦å é
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
```
**2ãå¤çº¿ç¨ç¯å¢ä½¿ç¨ååç±»ä¿è¯çº¿ç¨å®å
¨ï¼åºæ¬æ°æ®ç±»åï¼**
```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) {
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 < Person > ar = new AtomicReference < Person > ();
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