# CAS
é¢è¯å®ï¼äºè§£CASåï¼
æï¼äºè§£ï¼**æä»¬å¨è¯»Concurrentå
ä¸çç±»çæºç æ¶ï¼åç°æ 论æ¯**ReenterLockå
é¨çAQSï¼è¿æ¯åç§Atomicå¼å¤´çååç±»ï¼å
é¨é½åºç¨å°äº`CAS`ï¼å¹¶ä¸å¨è°ç¨getAndAddIntæ¹æ³ä¸ï¼ä¼æcompareAndSwapIntæ¹æ³ãå
¶å®é½æ¯è°ç¨unsafe.compareAndSwap()æ¹æ³ã
## compareAndSwapInt
ç»è¯´compareAndSwapIntæ¹æ³ï¼é£å²ä¸æ¯è¦çæºç ï¼
```cpp
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj); // oop å®å
¨ç¹ å¼ç¨
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); // 计ç®åç§»å°å
return (jint)(Atomic::cmpxchg(x, addr, e)) == e; // ååæä½ï¼æ¯è¾åæ´æ°
UNSAFE_END
```
Javaä¸ç`compareAndSwapIntï¼obj, offset, expect, updateï¼`æ¯è¾æ¸
æ¥ï¼**ææå°±æ¯å¦æ`obj`å
ç`value`å`expect`ç¸çï¼å°±è¯ææ²¡æå
¶ä»çº¿ç¨æ¹åè¿è¿ä¸ªåéï¼é£ä¹å°±æ´æ°å®ä¸º`update`ï¼å¦æè¿ä¸æ¥ç`CAS`没ææåï¼é£å°±éç¨èªæçæ¹å¼ç»§ç»è¿è¡`CAS`æä½**ï¼ååºä¹ä¸çè¿ä¹æ¯ä¸¤ä¸ªæ¥éª¤äºåï¼å
¶å®å¨`JNI`鿝åå©äºä¸ä¸ª`CPU`æä»¤å®æçãæä»¥è¿æ¯ååæä½ã
ååæä½ï¼å¯ç解为è¦ä¹è¿äºè¡ä¸ºé½æ§è¡ï¼ä¸è¢«ææ°ï¼è¦ä¸é½ä¸æ§è¡ãå®å¨ä¸è¡ï¼å°±çè§£ä¸ºä¸²è¡æä½ï¼
åç»è¯´è¿ä¸ªcpuæä»¤ï¼é£å°±è¦ç该æºç äºï¼
```hpp
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
int mp = os::is_MP(); // è¿åå¤çå¨ï¼å¤ææ¯å¤æ ¸è¿æ¯åæ ¸ï¼åæ ¸çç¥lockåç¼ï¼
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" // æ¯è¾
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "cc", "memory");
return exchange_value;
}
```
è°ç¨äº`Atomic::cmpxchg(x, addr, e)`, å
¶ä¸åæ°**xæ¯å³å°æ´æ°çå¼**ï¼åæ°**eæ¯åå
åçå¼**ã代ç ä¸è½çå°cmpxchgæåºäºå个平å°çå®ç°ã
## ABA
é¢è¯å®ï¼ç¥éABAé®é¢åï¼
æï¼ç¥éï¼æè¿°: 第ä¸ä¸ªçº¿ç¨åå°äºåé x çå¼ Aï¼ç¶åå·´æå·´æå¹²å«çäºï¼æ»ä¹å°±æ¯åªæ¿å°äºåé x çå¼ Aãè¿æ®µæ¶é´å
第äºä¸ªçº¿ç¨**ä¹åå°äºåé x çå¼ Aï¼ç¶åæåé x ç弿¹ä¸º Bï¼ç¶åå·´æå·´æå¹²å«çäºï¼æååæåé x çå¼å为 A** ï¼ç¸å½äºè¿åäºï¼ãå¨è¿ä¹å第ä¸ä¸ªçº¿ç¨ç»äºè¿è¡äºåé x çæä½ï¼ä½æ¯æ¤æ¶**åé x çå¼è¿æ¯ A**ï¼æä»¥ compareAndSet æä½æ¯æåã
è§£å³æ¹æ³ï¼**ç®åå¨JDKçatomicå
éæä¾äºä¸ä¸ªç±»`AtomicStampedReference`æ¥è§£å³ABAé®é¢ã**说ç½äºï¼å°±æ¯çæ¬å·
举ä¸ä¸ªä¾åï¼
```java
public class ABADemo {
static AtomicInteger atomicInteger = new AtomicInteger(100);
static AtomicStampedReference