# æ·±å
¥çè§£ volatile å
³é®å
* [æ·±å
¥çè§£ volatile å
³é®å](#æ·±å
¥çè§£-volatile-å
³é®å)
* [å
ä»å
忍¡åè°èµ·](#å
ä»å
忍¡åè°èµ·)
* [JVM å
忍¡å](#jvm-å
忍¡å)
* [å¹¶åç¼ç¨ä¸çä¸ä¸ªä¸»è¦é®é¢](#å¹¶åç¼ç¨ä¸çä¸ä¸ªä¸»è¦é®é¢)
* [å¯è§æ§é®é¢](#å¯è§æ§é®é¢)
* [ååæ§é®é¢](#ååæ§é®é¢)
* [æåºæ§é®é¢](#æåºæ§é®é¢)
* [volatile çå®ç°åç](#volatile-çå®ç°åç)
* [å¯è§æ§](#å¯è§æ§)
* [ååæ§](#ååæ§)
* [å
³é®æ¦å¿µ](#å
³é®æ¦å¿µ)
* [å¦ä½æ£ç¡®çä½¿ç¨ volatile åé](#å¦ä½æ£ç¡®ç使ç¨-volatile-åé)
* [ç¶ææ å¿](#ç¶ææ å¿)
* [å鿣æ¥é](#å鿣æ¥é)
* [读-åé](#读-åé)
volatile è¿ä¸ªå
³é®å大家é½ä¸éçï¼è¿ä¸ªå
³é®åä¸è¬é常ç¨äºå¹¶åç¼ç¨ä¸ï¼æ¯ Java èææºæä¾çè½»éå忥æºå¶ï¼ä½ å¯è½ç¥é volatile æ¯å¹²å¥çï¼ä½æ¯ä½ æªå¿
è½å¤æ¸
æ°æäºçç¥é volatile çå®ç°æºå¶ï¼ä»¥å volatile è§£å³äºä»ä¹é®é¢ï¼è¿ç¯æç« æå°±æ¥å¸¦å¤§å®¶è§£æä¸æ³¢ã
volatile è½å¤ä¿è¯å
±äº«åéä¹é´ç `å¯è§æ§`ï¼å
±äº«å鿝åå¨å åºçï¼èå åºåä¸å
忍¡åæå
³ï¼æä»¥æä»¬è¦è volatile ï¼å°±éè¦é¦å
äºè§£ä¸ä¸ JVM å
忍¡åï¼è JVM 忝åå
åè¿è¡äº¤äºçï¼æä»¥å¨è JVM å
忍¡ååï¼æä»¬è¿éè¦äºè§£ä¸ä¸æä½ç³»ç»å±é¢ä¸å
忍¡åçç¸å
³æ¦å¿µã
## å
ä»å
忍¡åè°èµ·
è®¡ç®æºå¨æ§è¡ç¨åºæ¶ï¼ä¼ä»å
åä¸è¯»åæ°æ®ï¼ç¶åå è½½å° CPU ä¸è¿è¡ãç±äº CPU æ§è¡æä»¤çéåº¦è¦æ¯ä»å
åä¸è¯»åååå
¥çé度快çå¤ï¼æä»¥å¦ææ¯æ¡æä»¤é½è¦åå
å交äºçè¯ï¼ä¼å¤§å¤§éä½ CPU çè¿è¡é度ï¼é ææè´µç CPU æ§è½æèï¼ä¸ºäºè§£å³è¿ç§é®é¢ï¼è®¾è®¡äº **CPU é«éç¼å**ãæäº CPU é«éç¼ååï¼CPU å°±ä¸åéè¦é¢ç¹çåå
å交äºäºï¼æé«éç¼åå°±è¡äºï¼è CPU é«éç¼åï¼å°±æ¯æä»¬ç»å¸¸è¯´ç L1 ãL2ãL3 cacheã
å½ç¨åºå¨è¿è¡è¿ç¨ä¸ï¼ä¼å°è¿ç®éè¦çæ°æ®ä»ä¸»åå¤å¶ä¸ä»½å° CPU çé«éç¼åä¸ï¼å¨ CPU è¿è¡è®¡ç®æ¶å°±å¯ä»¥ç´æ¥ä»å®çé«éç¼åè¯»åæ°æ®ï¼å½è¿ç®ç»æä¹åï¼åå°é«éç¼åä¸çæ°æ®å·æ°å°ä¸»åä¸ã
å°±æ¿æä»¬å¸¸è¯´ç
```java
i = i + 1
```
æ¥ä¸¾ä¾å
å½ CPU æ§è¡è¿æ¡è¯å¥æ¶ï¼ä¼å
ä»å
åä¸è¯»å i çå¼ï¼å¤å¶ä¸ä»½å°é«éç¼åå½ä¸ï¼ç¶å CPU æ§è¡æä»¤å¯¹ i è¿è¡å 1 æä½ï¼åå°æ°æ®åå
¥é«éç¼åï¼æåå°é«éç¼åä¸ i ææ°çå¼å·æ°å°ä¸»åå½ä¸ã
è¿ä¸ªä»£ç å¨å线ç¨ä¸è¿è¡æ¯æ²¡æä»»ä½é®é¢çï¼ä½æ¯å¨å¤çº¿ç¨ä¸è¿è¡å°±ä¼æé®é¢äºï¼å 为æ¯ä¸ª CPU é½å¯ä»¥è¿è¡ä¸æ¡çº¿ç¨ï¼çº¿ç¨å°±æ¯ç¨åºçé¡ºåºæ§è¡æµï¼å æ¤æ¯ä¸ªçº¿ç¨è¿è¡æ¶æèªå·±çé«éç¼åï¼å¯¹åæ ¸ CPU æ¥è¯´ï¼å
¶å®ä¹ä¼åºç°è¿ç§é®é¢ï¼åªä¸è¿æ¯ä»¥çº¿ç¨è°åº¦ç形弿¥å嫿§è¡çï¼ãæ¬ææä»¬ä»¥å¤æ ¸ CPU ä¸ºä¾æ¥è®²è§£è¯´æã
æ¯å¦åæ¶æ 2 ä¸ªçº¿ç¨æ§è¡è¿æ®µä»£ç ï¼åå¦åå§æ¶ i çå¼ä¸º 0ï¼é£ä¹æä»¬å¸æä¸¤ä¸ªçº¿ç¨æ§è¡å®ä¹å i çå¼å为 2ï¼ä½æ¯äºå®ä¼æ¯è¿æ ·åï¼
å¯è½åå¨ä¸é¢ä¸ç§æ
åµï¼åå§æ¶ï¼ä¸¤ä¸ªçº¿ç¨åå«è¯»å i çå¼åå
¥åèªæå¨ç CPU é«éç¼åä¸ï¼ç¶åçº¿ç¨ 1 æ§è¡å 1 æä½ï¼æ i çææ°å¼ 1 åå
¥å°å
åãæ¤æ¶çº¿ç¨ 2 çé«éç¼åå½ä¸ i çå¼è¿æ¯ 0ï¼è¿è¡å 1 æä½ä¹åï¼i çå¼ä¸º 1ï¼ç¶åçº¿ç¨ 2 æ i çå¼åå
¥å
åã
æç»ç»æ i ç弿¯ 1ï¼è䏿¯ 2ãè¿å°±æ¯èåç**ç¼åä¸è´æ§**é®é¢ãé常称è¿ç§è¢«å¤ä¸ªçº¿ç¨è®¿é®çåé为å
±äº«åéã
ä¹å°±æ¯è¯´ï¼å¦æä¸ä¸ªåéå¨å¤ä¸ª CPU ä¸é½åå¨ç¼åï¼ä¸è¬å¨å¤çº¿ç¨ç¼ç¨æ¶æä¼åºç°ï¼ï¼å°±å¾å¯è½åå¨ç¼åä¸ä¸è´çé®é¢ã
## JVM å
忍¡å
æä»¬ä¸é¢è¯´å°ï¼å
±äº«åéä¼åå¨ç¼åä¸ä¸è´çé®é¢ï¼ç¼åä¸ä¸è´é®é¢æ¢ç§è¯´æ³å°±æ¯**线ç¨å®å
¨é®é¢**ï¼é£ä¹å
±äº«åéå¨ Java 䏿¯å¦ä½åå¨çå¢ï¼JVM ä¸ææ²¡ææä¾çº¿ç¨å®å
¨çåéæè
æ°æ®å¢ï¼
è¿å°±è¦èè JVM å
忍¡åçé®é¢äºï¼å¾ç¤ºå¦ä¸

- `èææºæ ` : Java èææºæ æ¯çº¿ç¨ç§æçæ°æ®åºï¼Java èææºæ ççå½å¨æä¸çº¿ç¨ç¸åï¼èææºæ 乿¯å±é¨åéçåå¨ä½ç½®ãæ¹æ³å¨æ§è¡è¿ç¨ä¸ï¼ä¼å¨èææºæ ç§å建ä¸ä¸ª `æ 帧(stack frame)`ã
- `æ¬å°æ¹æ³æ `: æ¬å°æ¹æ³æ 乿¯çº¿ç¨ç§æçæ°æ®åºï¼æ¬å°æ¹æ³æ åå¨çåºåä¸»è¦æ¯ Java ä¸ä½¿ç¨ `native` å
³é®åä¿®é¥°çæ¹æ³æåå¨çåºåã
- `ç¨åºè®¡æ°å¨`ï¼ç¨åºè®¡æ°å¨ä¹æ¯çº¿ç¨ç§æçæ°æ®åºï¼è¿é¨ååºåç¨äºåå¨çº¿ç¨çæä»¤å°åï¼ç¨äºå¤æçº¿ç¨ç忝ã循ç¯ã跳转ãå¼å¸¸ã线ç¨åæ¢åæ¢å¤çåè½ï¼è¿äºé½éè¿ç¨åºè®¡æ°å¨æ¥å®æã
- `æ¹æ³åº`ï¼æ¹æ³åºæ¯å个线ç¨å
±äº«çå
ååºåï¼å®ç¨äºåå¨èææºå è½½ç 类信æ¯ã常éãéæåéã峿¶ç¼è¯å¨ç¼è¯åç代ç çæ°æ®ã
- `å `ï¼ å æ¯çº¿ç¨å
±äº«çæ°æ®åºï¼å æ¯ JVM 䏿大çä¸ååå¨åºåï¼ææç对象å®ä¾é½ä¼åé
å¨å ä¸
- `è¿è¡æ¶å¸¸éæ± `ï¼è¿è¡æ¶å¸¸éæ± å被称为 `Runtime Constant Pool`ï¼è¿ååºåæ¯æ¹æ³åºçä¸é¨åï¼å®çååéå¸¸æææï¼å®å¹¶ä¸è¦æ±å¸¸éä¸å®åªæå¨ç¼è¯ææè½äº§çï¼ä¹å°±æ¯å¹¶éç¼è¯æé´å°å¸¸éæ¾å¨å¸¸éæ± ä¸ï¼è¿è¡æé´ä¹å¯ä»¥å°æ°ç叏鿾å
¥å¸¸éæ± ä¸ï¼String ç intern æ¹æ³å°±æ¯ä¸ä¸ªå
¸åçä¾åã
æ ¹æ®ä¸é¢çæè¿°å¯ä»¥çå°ï¼ä¼äº§çç¼åä¸ä¸è´é®é¢ï¼çº¿ç¨å®å
¨é®é¢ï¼çæ**å åºåæ¹æ³åº**ãèèææºæ ãæ¬å°æ¹æ³æ ãç¨åºè®¡æ°å¨æ¯çº¿ç¨ç§æï¼ç±çº¿ç¨å°éçåå ï¼å®ä»¬ä¸åå¨çº¿ç¨å®å
¨é®é¢ã
> é对线ç¨å®å
¨é®é¢ï¼ææ²¡æè§£å³åæ³å¢ï¼
ä¸è¬æ
åµä¸ï¼Java ä¸è§£å³ç¼åä¸ä¸è´çæ¹æ³æä¸¤ç§ï¼ç¬¬ä¸ç§å°±æ¯ `synchronized` 使ç¨çæ»çº¿éæ¹å¼ï¼ä¹å°±æ¯å¨æ»çº¿ä¸å£°è¨ `LOCK#` ä¿¡å·ï¼ç¬¬äºç§å°±æ¯èåç `MESI` åè®®ãè¿ä¸¤ç§é½æ¯ç¡¬ä»¶å±é¢æä¾çè§£å³æ¹å¼ã
æä»¬å
æ¥è¯´ä¸ä¸ç¬¬ä¸ç§æ»çº¿éçæ¹å¼ãéè¿å¨æ»çº¿ä¸å£°è¨ LOCK# ä¿¡å·ï¼è½å¤ææçé»å¡å
¶ä» CPU å¯¹äºæ»çº¿ç访é®ï¼ä»è使å¾åªè½æä¸ä¸ª CPU 访é®åéæå¨çå
åãå¨ä¸é¢ç i = i + 1 代ç 示ä¾ä¸ï¼å¨ä»£ç æ§è¡çè¿ç¨ä¸ï¼å£°è¨äº LOCK# ä¿¡å·åï¼é£ä¹åªæçå¾
i = i + 1 çç»ææ§è¡å®æ¯å¹¶åºç¨å°å
ååï¼æ»çº¿éæä¼è§£å¼ï¼å
¶ä» CPU æè½å¤ç»§ç»è®¿é®å
åä¸çåéï¼åç»§ç»æ§è¡åé¢ç代ç ï¼è¿æ ·å°±è§£å³äºç¼åä¸ä¸è´é®é¢ã

使¯ä¸é¢çæ¹å¼ä¼æä¸ä¸ªé®é¢ï¼ç±äºå¨é使»çº¿æé´ï¼å
¶ä» CPU æ æ³è®¿é®å
åï¼å¯¼è´æçä½ä¸ã
å¨ JDK 1.6 ä¹åï¼ä¼åäº synchronized å£°è¨ LOCK# çæ¹å¼ï¼ä¸å对æ»çº¿è¿è¡éå®ï¼è½¬èéåäºå¯¹ CPU ç¼åè¡è¿è¡éå®ï¼å 为æ¬ç¯æç« 䏿¯ä»ç» synchronized å®ç°ç»èçæç« ï¼æä»¥ä¸å对è¿ç§æ¹å¼è¿è¡è¯¦ç»ä»ç»ï¼è¯»è
åªéè¦ç¥éå¨ä¼åä¹åï¼synchronized çæ§è½ä¸åæä¸ºå¹¶åé®é¢çç¶é¢äºã
MESI å议就æ¯ç¼åä¸è´æ§åè®®ï¼å³ **Modifiedï¼è¢«ä¿®æ¹ï¼Exclusiveï¼ç¬å çï¼ Sharedï¼å
±äº«çï¼ Or Invalidï¼æ æçï¼**ãMESI çåºæ¬ææ³å°±æ¯å¦æåç° CPU æä½çæ¯å
±äº«åéï¼å
¶ä» CPU ä¸ä¹ä¼åºç°è¿ä¸ªå
±äº«åéç坿¬ï¼å¨ CPU æ§è¡ä»£ç æé´ï¼ä¼ååºä¿¡å·éç¥å
¶ä» CPU èªå·±æ£å¨ä¿®æ¹å
±äº«åéï¼å
¶ä» CPU æ¶å°éç¥å就伿èªå·±çå
±äº«åéç½®ä¸ºæ æç¶æã

## å¹¶åç¼ç¨ä¸çä¸ä¸ªä¸»è¦é®é¢
### å¯è§æ§é®é¢
å¨åæ ¸ CPU æ¶ä»£ï¼ææç线ç¨å
±ç¨ä¸ä¸ª CPUï¼CPU ç¼ååå
åçä¸è´æ§é®é¢å®¹æè§£å³ï¼æä»¬è¿æ¿ä¸é¢ç i = 1 + 1 æ¥ä¸¾ä¾ï¼CPU å å
åä¹é´å¦æç¨å¾æ¥è¡¨ç¤ºçè¯ææ³ä¼æ¯ä¸é¢è¿æ ·ã

å¨å¤æ ¸æ¶ä»£ï¼æ¯ä¸ªæ ¸é½è½å¤ç¬ç«çè¿è¡ä¸ä¸ªçº¿ç¨ï¼æ¯ä¸ª CPU 齿èªå·±çç¼åï¼è¿æ¶ CPU ç¼åä¸å
åçæ°æ®ä¸è´æ§å°±æ²¡é£ä¹å®¹æè§£å³äºï¼å½å¤ä¸ªçº¿ç¨å¨ä¸åç CPU 䏿§è¡æ¶ï¼è¿äºçº¿ç¨ä½¿ç¨çæ¯ä¸åç CPU ç¼åã

å 为 i 没æç»è¿ä»»ä½çº¿ç¨å®å
¨æªæ½çä¿æ¤ï¼å¤ä¸ªçº¿ç¨ä¼å¹¶åä¿®æ¹ i çå¼ï¼æä»¥æä»¬è®¤ä¸º i 䏿¯çº¿ç¨å®å
¨çï¼å¯¼è´è¿ç§ç»æçåºç°æ¯ç±äº aThread å bThread ä¸è¯»åç i å¼å½¼æ¤ä¸å¯è§ï¼æä»¥è¿æ¯ç±äº `å¯è§æ§` 导è´ç线ç¨å®å
¨é®é¢ã
### ååæ§é®é¢
å½ä¸¤ä¸ªçº¿ç¨å¼å§è¿è¡åï¼æ¯ä¸ªçº¿ç¨é½ä¼æ i çå¼è¯»å
¥å° CPU ç¼åä¸ï¼åæ§è¡ + 1 æä½ï¼ç¶åæ + 1 ä¹åçå¼åå
¥å
åãå 为线ç¨é´é½æåèªçèææºæ åç¨åºè®¡æ°å¨ï¼ä»ä»¬å½¼æ¤ä¹é´æ²¡ææ°æ®äº¤æ¢ï¼æä»¥å½ aThread æ§è¡ + 1 æä½åï¼ä¼ææ°æ®åå
¥å°å
åï¼åæ¶ bThread æ§è¡ + 1 æä½åï¼ä¹ä¼ææ°æ®åå
¥å°å
åï¼å 为 CPU æ¶é´ççæ§è¡å¨ææ¯ä¸ç¡®å®çï¼æä»¥ä¼åºç°å½ aThread è¿æ²¡æææ°æ®åå
¥å
åæ¶ï¼bThread å°±ä¼è¯»åå
åä¸çæ°æ®ï¼ç¶åæ§è¡ + 1æä½ï¼åååå
åï¼ä»èè¦ç i çå¼ã

### æåºæ§é®é¢
å¨å¹¶åç¼ç¨ä¸è¿æå¸¦æ¥è®©äººé常头ç¼ç `æåºæ§` é®é¢ï¼æåºæ§é¡¾åæä¹å°±æ¯é¡ºåºæ§ï¼å¨è®¡ç®æºä¸æçå°±æ¯æä»¤çå
åæ§è¡é¡ºåºãä¸ä¸ªé常æ¾èæè§çä¾åå°±æ¯ JVM ä¸ç`ç±»å è½½`ã

è¿æ¯ä¸ä¸ª JVM å 载类çè¿ç¨å¾ï¼ä¹ç§°ä¸ºç±»ççå½å¨æï¼ç±»ä»å è½½å° JVM å°å¸è½½ä¸å
±ä¼ç»åäºä¸ªé¶æ®µ **å è½½ãè¿æ¥ãåå§åã使ç¨ãå¸è½½**ãè¿äºä¸ªè¿ç¨çæ§è¡é¡ºåºæ¯ä¸å®çï¼ä½æ¯å¨è¿æ¥é¶æ®µï¼ä¹ä¼å为ä¸ä¸ªè¿ç¨ï¼å³ **éªè¯ãåå¤ãè§£æ** é¶æ®µï¼è¿ä¸ä¸ªé¶æ®µçæ§è¡é¡ºåºä¸æ¯ç¡®å®çï¼é常交åè¿è¡ï¼å¨ä¸ä¸ªé¶æ®µçæ§è¡è¿ç¨ä¸ä¼æ¿æ´»å¦ä¸ä¸ªé¶æ®µã
卿§è¡ç¨åºçè¿ç¨ä¸ï¼ä¸ºäºæé«æ§è½ï¼ç¼è¯å¨åå¤çå¨é常ä¼å¯¹æä»¤è¿è¡éæåºãéæåºä¸»è¦å为ä¸ç±»
* **ç¼è¯å¨ä¼åçéæåº**ï¼ç¼è¯å¨å¨ä¸æ¹åå线ç¨è¯ä¹çæ
åµä¸ï¼ä¼å¯¹æ§è¡è¯å¥è¿è¡éæ°æåºã
* **æä»¤ééæåº**ï¼ç°ä»£æä½ç³»ç»ä¸çå¤çå¨é½æ¯å¹¶è¡çï¼å¦ææ§è¡è¯å¥ä¹é´ä¸å卿°æ®ä¾èµæ§ï¼å¤çå¨å¯ä»¥æ¹åè¯å¥çæ§è¡é¡ºåº
* **å
åéæåº**ï¼ç±äºå¤çå¨ä¼ä½¿ç¨è¯»/åç¼å²åºï¼åºäºæ§è½çåå ï¼å
åä¼å¯¹è¯»/åè¿è¡éæåº
ä¹å°±æ¯è¯´ï¼è¦æ³å¹¶åç¨åºæ£ç¡®å°æ§è¡ï¼å¿
é¡»è¦ä¿è¯ååæ§ãå¯è§æ§ä»¥åæåºæ§ãåªè¦æä¸ä¸ªæ²¡æè¢«ä¿è¯ï¼å°±æå¯è½ä¼å¯¼è´ç¨åºè¿è¡ä¸æ£ç¡®ã
## volatile çå®ç°åç
ä¸é¢èäºè¿ä¹å¤ï¼ä½ å¯è½é½è¦å¿äºè¿ç¯æç« çæ
äºä¸»è§äºå§ï¼ä¸»è§æ°¸è¿åå¨äºæä»¬å¿ä¸ ......
å
¶å®ä¸é¢èçè¿äºï¼é½æ¯å¨ä¸º volatile åéºå«ã
å¨å¹¶åç¼ç¨ä¸ï¼æéè¦å¤ççå°±æ¯çº¿ç¨ä¹é´ç`éä¿¡`å线ç¨é´ç`忥`é®é¢ï¼ä¸é¢çå¯è§æ§ãååæ§ãæåºæ§ä¹æ¯è¿ä¸¤ä¸ªé®é¢å¸¦æ¥çã
### å¯è§æ§
è volatile å°±æ¯ä¸ºäºè§£å³è¿äºé®é¢èåå¨çãJava è¯è¨è§è对 volatile ä¸äºå®ä¹ï¼Java è¯è¨ä¸ºäºç¡®ä¿è½å¤å®å
¨ç访é®å
±äº«åéï¼æä¾äº volatile è¿ä¸ªå
³é®åï¼volatile æ¯ä¸ç§**è½»éçº§åæ¥**æºå¶ï¼å®å¹¶ä¸ä¼å¯¹å
±äº«åéè¿è¡å éï¼ä½å¨æäºæ
åµä¸è¦æ¯å é**æ´å æ¹ä¾¿**ï¼å¦æä¸ä¸ªå段被声æä¸º volatileï¼Java 线ç¨å
忍¡åè½å¤ç¡®ä¿ææçº¿ç¨è®¿é®è¿ä¸ªåéçå¼é½æ¯ä¸è´çã
䏿¦å
±äº«åé被 volatile 修饰åï¼å°±å
·æäºä¸é¢ä¸¤ç§å«ä¹
1. ä¿è¯äºè¿ä¸ªå段çå¯è§æ§ï¼ä¹å°±æ¯è¯´ææçº¿ç¨é½è½å¤"çå°"è¿ä¸ªåéçå¼ï¼å¦ææä¸ª CPU ä¿®æ¹äºè¿ä¸ªåéçå¼ä¹åï¼å
¶ä» CPU ä¹è½å¤è·å¾éç¥ã
2. è½å¤ç¦æ¢æä»¤çéæåº
ä¸é¢æä»¬æ¥ç䏿®µä»£ç ï¼è¿ä¹æ¯æä»¬ç¼åå¹¶å代ç ä¸ç»å¸¸ä¼ä½¿ç¨å°ç
```java
boolean isStop = false;
while(!isStop){
...
}
isStop = true;
```
å¨è¿æ®µä»£ç ä¸ï¼å¦æçº¿ç¨ä¸æ£å¨æ§è¡ while 循ç¯ï¼è线ç¨äºæ isStop æ¹ä¸º true ä¹åï¼è½¬èå»åå
¶ä»äºæ
ï¼å 为线ç¨ä¸å¹¶ä¸ç¥é线ç¨äºæ isStop æ¹ä¸º true ï¼æä»¥çº¿ç¨ä¸å°±ä¼ä¸ç´è¿è¡ä¸å»ã
妿 isStop ç¨ volatile 修饰ä¹åï¼é£ä¹äºæ
å°±ä¼åçä¸ä¸æ ·äºã
ä½¿ç¨ volatile ä¿®é¥°äº isStop ä¹åï¼å¨çº¿ç¨äºæ isStop æ¹ä¸º true ä¹åï¼ä¼å¼ºå¶å°å
¶åå
¥å
åï¼å¹¶ä¸ä¼æçº¿ç¨ä¸ä¸ isStop çå¼ç½®ä¸ºæ æï¼è¿ä¸ªå¼å®é
䏿¯å¨ç¼åå¨ CPU ä¸çç¼åè¡éï¼ï¼å½çº¿ç¨ä¸ç»§ç»æ§è¡ä»£ç çæ¶åï¼ä¼ä»å
åä¸éæ°è¯»å isStop çå¼ï¼æ¤æ¶ isStop çå¼å°±æ¯æ£ç¡®çå
åå°åçå¼ã
volatile æä¸é¢ä¸¤æ¡å®ç°ååï¼å
¶å®è¿ä¸¤æ¡ååæä»¬å¨ä¸é¢ä»ç»çæ¶åå·²ç»æè¿äºï¼ä¸ç§æ¯æ»çº¿éçæ¹å¼ï¼æä»¬åé¢è¯´æ»çº¿éçæ¹å¼å¼éæ¯è¾å¤§ï¼æä»¥åé¢è®¾è®¡äººååäºä¼åï¼éç¨äºéç¼åçæ¹å¼ãå¦å¤ä¸ç§æ¯ MESI åè®®çæ¹å¼ã
* å¨ IA-32 æ¶æè½¯ä»¶å¼åè
çæåä¸ï¼æä¸ç§ Lock åç¼æä»¤ï¼è¿ç§æä»¤è½å¤å£°è¨ LOCK# ä¿¡å·ï¼å¨æè¿çå¤çå¨ä¸ï¼LOCK# ä¿¡å·ç¨äºéç¼åï¼ç尿令æ§è¡å®æ¯åï¼ä¼æç¼åçå
容ååå
åï¼è¿ç§æä½ä¸è¬å被称为**ç¼åéå®**ã
* å½ç¼åååå
ååï¼IA-32 å IA-64 å¤çå¨ä¼ä½¿ç¨ MESI åè®®æ§å¶å
é¨ç¼ååå
¶ä»å¤çå¨ä¸è´ãIA-32 å IA-64 å¤çå¨è½å¤å
æ¢å
¶ä»å¤çå¨è®¿é®ç³»ç»å
é¨ç¼åï¼å½å
åå¼ä¿®æ¹åï¼å¤çå¨ä¼ä»å
åä¸éæ°è¯»åå
åå¼è¿è¡æ°çç¼åè¡å¡«å
ã
ç±æ¤å¯è§ï¼volatile è½å¤ä¿è¯çº¿ç¨çå¯è§æ§ã
>é£ä¹ volatile è½å¤ä¿è¯ååæ§åï¼
### ååæ§
æä»¬è¿æ¯ä»¥ i = i + 1 è¿ä¸ªä¾åæ¥è¯´æä¸ä¸ï¼i = i + 1 å为ä¸ä¸ªæä½
* 读å i çå¼
* èªå¢ i çå¼
* æ i çå¼åä¼å
å
æä»¬ç¥éï¼volatile è½å¤ä¿è¯ä¿®æ¹ i çå¼å¯¹å
¶ä»çº¿ç¨å¯è§ï¼æä»¥æä»¬æ¤æ¶å设线ç¨ä¸æ§è¡ i ç读åæä½ï¼æ¤æ¶åçäºçº¿ç¨åæ¢ï¼çº¿ç¨äºè¯»åå°ææ° i ç弿¯ 0 ï¼ç¶å线ç¨å次åç忢ï¼çº¿ç¨ä¸æ i ç弿¹ä¸º 1ï¼çº¿ç¨åæ¬¡åæ¢ï¼å ä¸ºæ¤æ¶ i çå¼è¿æ²¡æåºç¨å°å
åï¼æä»¥çº¿ç¨ i åæ ·æ i ç弿¹ä¸º 1 åï¼çº¿ç¨å次åç忢ï¼çº¿ç¨ä¸æ i çå¼åå
¥å
ååï¼å次åç忢ï¼çº¿ç¨äºå次æ i çå¼åä¼å
åï¼æä»¥æ¤æ¶ï¼è½ç¶å
å弿¹äºä¸¤æ¬¡ï¼ä½æ¯æåçç»æå´ä¸æ¯ 2ã

>é£ä¹ volatile ä¸è½ä¿è¯ååæ§ï¼é£ä¹è¯¥å¦ä½ä¿è¯ååæ§å¢ï¼
å¨ JDK 5 ç java.util.concurrent.atomic å
䏿ä¾äºä¸äºååæä½ç±»ï¼ä¾å¦ AtomicIntegerãAtomicLongãAtomicBooleanï¼è¿äºæä½æ¯ååæ§æä½ãå®ä»¬æ¯å©ç¨ CAS æ¥å®ç°ååæ§æä½çï¼Compare And Swapï¼ï¼CASå®é
䏿¯å©ç¨å¤ç卿ä¾ç `CMPXCHG` æä»¤å®ç°çï¼èå¤ç卿§è¡ CMPXCHG æä»¤æ¯ä¸ä¸ªååæ§æä½ã
详æ
å¯ä»¥åèç¬è
çè¿ç¯æç« [ä¸åº Atomic XXX çé幻乿
](https://mp.weixin.qq.com/s?__biz=MzkwMDE1MzkwNQ==&mid=2247495805&idx=1&sn=74cb9ee585edf13b3af7431bbb0f4e0e&chksm=c04ae723f73d6e35e0212472778b997ebeae428d6562e88bf15b311c87241a32331af7f42101&token=530741505&lang=zh_CN#rd)ã
>é£ä¹ volatile è½ä¸è½ä¿è¯æåºæ§å¢ï¼
è¿éå°±éè¦åä½ èä¸è volatile 对æåºæ§çå½±åäº
###æåºæ§
ä¸é¢æå°è¿ï¼éæåºå为ç¼è¯å¨éæåºãå¤çå¨éæåºåå
åéæåºãæä»¬è¯´ç volatile ä¼ç¦ç¨æä»¤éæåºï¼å®é
ä¸ volatile ç¦ç¨çæ¯ç¼è¯å¨éæåºåå¤çå¨éæåºã
ä¸é¢æ¯ volatile ç¦ç¨éæåºçè§å

ä»è¿ä¸ªè¡¨ä¸å¯ä»¥çåºæ¥ï¼è¯»åæä½æåç§ï¼å³ä¸å ä»»ä½ä¿®é¥°çæ®é读ååä½¿ç¨ volatile 修饰ç读åã
ä»è¿ä¸ªè¡¨ä¸ï¼æä»¬å¯ä»¥å¾åºä¸é¢è¿äºç»è®º
* åªè¦ç¬¬äºä¸ªæä½ï¼è¿ä¸ªæä½å°±æçæ¯ä»£ç æ§è¡æä»¤ï¼æ¯ volatile 修饰çåæä½ï¼é£ä¹æ 论第ä¸ä¸ªæä½æ¯ä»ä¹ï¼é½ä¸è½è¢«éæåºã
* å½ç¬¬ä¸ä¸ªæä½æ¯ volatile 读æ¶ï¼ä¸ç®¡ç¬¬äºä¸ªæä½æ¯ä»ä¹ï¼é½ä¸è½è¿è¡éæåºã
* å½ç¬¬ä¸ä¸ªæä½æ¯ volatile åä¹åï¼ç¬¬äºä¸ªæä½æ¯ volatile 读/åé½ä¸è½éæåºã
为äºå®ç°è¿ç§æåºæ§ï¼ç¼è¯å¨ä¼å¨çæåèç ä¸ï¼ä¼å¨æä»¤åºå䏿å
¥**å
åå±é**æ¥ç¦æ¢ç¹å®ç±»åçå¤çå¨éæåºã
>è¿éæä»¬å
æ¥äºè§£ä¸ä¸å
åå±éçæ¦å¿µã
å
åå±éä¹å«å`æ
æ `ï¼å®æ¯ä¸ç§åºå±åè¯ãå®ä½¿å¾ CPU æç¼è¯å¨å¨å¯¹å
åè¿è¡æä½çæ¶å, è¦ä¸¥æ ¼æç
§ä¸å®çé¡ºåºæ¥æ§è¡, ä¹å°±æ¯è¯´å¨ memory barrier ä¹åçæä»¤å memory barrier ä¹åçæä»¤ä¸ä¼ç±äºç³»ç»ä¼åçåå è导è´ä¹±åºã
å
åå±éæä¾äºä¸¤ä¸ªåè½ãé¦å
ï¼å®ä»¬éè¿ç¡®ä¿ä»å¦ä¸ä¸ª CPU æ¥çå±éçä¸¤è¾¹çæææä»¤é½æ¯æ£ç¡®çç¨åºé¡ºåºï¼å
¶æ¬¡å®ä»¬å¯ä»¥å®ç°å
åæ°æ®å¯è§æ§ï¼ç¡®ä¿å
åæ°æ®ä¼åæ¥å° CPU ç¼ååç³»ç»ã
ä¸åè®¡ç®æºä½ç³»ç»æä¸é¢çå
åå±éä¹ä¸ä¸æ ·ï¼é常éè¦è®¤çç 读硬件æåæ¥ç¡®å®ï¼æä»¥æä»¬ç主è¦ç 究对象æ¯åºäº x86 çå
åå±éï¼é常æ
åµä¸ï¼ç¡¬ä»¶ä¸ºæä»¬æä¾äºåç§ç±»åçå
åå±éã
* LoadLoad å±é
å®çæ§è¡é¡ºåºæ¯ Load1 ï¼ LoadLoad ï¼Load2 ï¼å
¶ä¸ç Load1 å Load2 齿¯å è½½æä»¤ãLoadLoad æä»¤è½å¤ç¡®ä¿æ§è¡é¡ºåºæ¯å¨ Load1 ä¹åï¼Load2 ä¹åï¼LoadLoad æä»¤æ¯ä¸ä¸ªæ¯è¾ææç鲿¢çå°æ§æ°æ®çæä»¤ã
* StoreStore å±é
å®çæ§è¡é¡ºåºæ¯ Store1 ï¼StoreStore ï¼Store2 ï¼åä¸é¢ç LoadLoad å±éçæ§è¡é¡ºåºç¸ä¼¼ï¼å®ä¹è½å¤ç¡®ä¿æ§è¡é¡ºåºæ¯å¨ Store1 ä¹åï¼Store2 ä¹åã
* LoadStore å±é
å®çæ§è¡é¡ºåºæ¯ Load1 ï¼ StoreLoad ï¼ Store2 ï¼ä¿è¯ Load1 çæ°æ®è¢«å è½½å¨ä¸è¿æ°æ®ç¸å
³ç Store2 åä¹åç store æä»¤ä¹åã
* StoreLoad å±é
å®çæ§è¡é¡ºåºæ¯ Store1 ï¼ StoreLoad ï¼ Load2 ï¼ä¿è¯ Store1 çæ°æ®è¢«å
¶ä» CPU çå°ï¼å¨æ°æ®è¢« Load2 åä¹åç load æä»¤å è½½ä¹åãä¹å°±æ¯è¯´ï¼å®ææç鲿¢ææ barrier ä¹åç stores 䏿æ barrier ä¹åç load ä¹±åºã
JMM éåäºä¿å®çç¥æ¥å®ç°å
åå±éï¼JMM 使ç¨çå
åå±éå¦ä¸

ä¸é¢æ¯ä¸ä¸ªä½¿ç¨å
åå±éç示ä¾
```java
class MemoryBarrierTest {
int a, b;
volatile int v, u;
void f() {
int i, j;
i = a;
j = b;
i = v;
j = u;
a = i;
b = j;
v = i;
u = j;
i = u;
j = b;
a = i;
}
}
```
è¿æ®µä»£ç è½ç¶æ¯è¾ç®åï¼ä½æ¯ä½¿ç¨äºä¸å°åéï¼çèµ·æ¥æäºä¹±ï¼æä»¬åç¼è¯ä¸ä¸æ¥åæä¸ä¸å
åå±éå¯¹è¿æ®µä»£ç çå½±åã
ä»åç¼è¯çä»£ç æä»¬æ¯çä¸å°å
åå±éçï¼å 为å
åå±éæ¯ä¸ç§ç¡¬ä»¶å±é¢çæä»¤ï¼åååèç æ¯è¯å®æ æ³çå°çãè½ç¶æ æ³çå°å
åå±éç硬件æä»¤ï¼ä½æ¯ JSR-133 为æä»¬è¯´æäºåªäºåèç ä¼åºç°å
åå±éã
* æ®éç读类似 getfield ãgetstatic ã ä¸å volatile ä¿®é¥°çæ°ç» load ã
* æ®éçå类似 putfield ã putstatic ã ä¸å volatile ä¿®é¥°çæ°ç» store ã
* volatile 读æ¯å¯ä»¥è¢«å¤ä¸ªçº¿ç¨è®¿é®ä¿®é¥°ç getfieldã getstatic åæ®µã
* volatile 忝å¯ä»¥è¢«å½ä¸ªçº¿ç¨è®¿é®ä¿®é¥°ç putfieldã putstatic åæ®µã
è¿ä¹å°±æ¯è¯´ï¼åªè¦æ¯æ®éç读åå ä¸äº volatile å
³é®åä¹åï¼å°±æ¯ volatile 读åï¼åååï¼æå¥½å说äºä¸å¥åºè¯ï¼ï¼å¹¶æ²¡æå
¶ä»ç¹æ®ç volatile ç¬æçæä»¤ã
æ ¹æ®è¿æ®µæè¿°ï¼æä»¬æ¥ç»§ç»åæä¸ä¸ä¸é¢çåèç ã
aãb æ¯å
¨å±åéï¼ä¹å°±æ¯å®ä¾åéï¼ä¸å volatile 修饰ï¼uãv æ¯ volatile 修饰çå
¨å±åéï¼iãj æ¯å±é¨åéã
é¦å
i = aãj = b åªæ¯æå
¨å±åéçå¼èµç»äºå±é¨åéï¼ç±äºæ¯è·å对象å¼ç¨çæä½ï¼æä»¥æ¯åèç æä»¤æ¯ getfield ã
ä»å®æ¹æåå°±å¯ä»¥ç¥æåå äºã

å°åå¨ https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html
ç±å
åå±éçè¡¨æ ¼å¯ç¥ï¼ç¬¬ä¸ä¸ªæä½æ¯æ®é读åçæ
åµä¸ï¼åªæç¬¬äºä¸ªæä½æ¯ volatile åæä¼è®¾ç½®å
åå±éã
ç»§ç»åä¸åæï¼éå°äº i = vï¼è¿ä¸ªæ¯æ volatile åéèµå¼ç»å±é¨åéï¼æ¯ä¸ç§ volatile 读ï¼åæ ·ç j = u 乿¯ä¸ç§ volatile è¯»ï¼æä»¥è¿ä¸¤ä¸ªæä½ä¹é´ä¼è®¾ç½® LoadLoad å±éã
ä¸é¢éå°äº a = i ï¼è¿æ¯ä¸ºå
¨å±åéèµå¼æä½ï¼æä»¥å
¶å¯¹åºçåèç æ¯ putfield

å°åå¨ https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html
æä»¥å¨ j = u å a = i ä¹é´ä¼å¢å LoadStore å±éãç¶å a = i å b = j æ¯ä¸¤ä¸ªæ®éåï¼æä»¥è¿ä¸¤ä¸ªæä½ä¹é´ä¸éè¦æå
åå±éã
ç»§ç»å¾ä¸é¢åæï¼ç¬¬ä¸ä¸ªæä½æ¯ b = j ï¼ç¬¬äºä¸ªæä½æ¯ v = i ä¹å°±æ¯ volatile åï¼æä»¥éè¦æ StoreStore å±éï¼åæ ·çï¼v = i å u = j ä¹é´ä¹éè¦æ StoreStore å±éã
第ä¸ä¸ªæä½æ¯ u = j å 第äºä¸ªæä½ i = u volatile 读ä¹é´éè¦ StoreLoad å±éã
æåä¸ç¹éè¦æ³¨æä¸ï¼å 为æå两个æä½æ¯æ®éè¯»åæ®éåï¼æä»¥æåéè¦æå
¥ä¸¤ä¸ªå
åå±éï¼é²æ¢ volatile è¯»åæ®é读/åéæåºã
ãJava å¹¶åç¼ç¨èºæ¯ãéé¢ä¹æå°äºè¿ä¸ªå
³é®ç¹ã

ä»ä¸é¢çåæå¯ç¥ï¼volatile å®ç°æåºæ§æ¯éè¿å
åå±éæ¥å®ç°çã
## å
³é®æ¦å¿µ
å¨ volatile å®ç°å¯è§æ§åæåºæ§çè¿ç¨ä¸ï¼æä¸äºå
³é®æ¦å¿µï¼cxuan è¿ééæ°ç»è¯»è
æå们å å¨ä¸ã
* ç¼å²è¡ï¼è±ææ¦å¿µæ¯ **cache line**ï¼å®æ¯ç¼åä¸å¯ä»¥åé
çæå°åå¨åä½ãå ä¸ºæ°æ®å¨å
åä¸ä¸æ¯ä»¥ç¬ç«ç项è¿è¡åå¨çï¼èæ¯ä»¥ä¸´è¿ 64 åèçæ¹å¼è¿è¡åå¨ã
* ç¼åè¡å¡«å
ï¼**cache line fill**ï¼å½ CPU æå
åçæ°æ®è½½å
¥ç¼åæ¶ï¼ä¼æä¸´è¿çå
± 64 åèçæ°æ®ä¸åæ¾å
¥åä¸ä¸ª Cache lineï¼å 为å±é¨æ§åçï¼ä¸´è¿çæ°æ®å¨å°æ¥è¢«è®¿é®çå¯è½æ§å¤§ã
* ç¼åå½ä¸ï¼**cache hit**ï¼å½ CPU ä»å
åå°å䏿忰æ®è¿è¡ç¼åè¡å¡«å
æ¶ï¼åç°æåçä½ç½®ä»ç¶æ¯ä¸æ¬¡è®¿é®çä½ç½®ï¼æ¤æ¶ CPU ä¼éæ©ä»ç¼åä¸è¯»åæä½æ°ï¼è䏿¯ä»å
åä¸åã
* åå½ä¸ï¼**write hit** ï¼å½å¤ç卿ç®å°æä½æ°ååå°å
åæ¶ï¼é¦å
伿£æ¥è¿ä¸ªç¼åçå
åå°åæ¯å¦å¨ç¼åè¡ä¸ï¼å¦æåå¨ä¸ä¸ªææçç¼åè¡ï¼åå¤çå¨ä¼å°è¿ä¸ªæä½æ°ååå°ç¼åï¼è䏿¯ååå°å
åï¼è¿ç§æ¹å¼è¢«ç§°ä¸ºåå½ä¸ã
* å
åå±éï¼**memory barriers**ï¼æ¯ä¸ç»ç¡¬ä»¶æä»¤ï¼æ¯ volatile å®ç°æåºæ§çåºç¡ã
* ååæä½ï¼**atomic operations**ï¼æ¯ä¸ç»ä¸å¯ä¸æçä¸ä¸ªæè
ä¸ç»æä½ã
## å¦ä½æ£ç¡®çä½¿ç¨ volatile åé
ä¸é¢æä»¬èäºè¿ä¹å¤ volatile çåçï¼ä¸é¢æä»¬å°±æ¥è°ä¸è° volatile ç使ç¨é®é¢ã
volatile éå¸¸ç¨æ¥å synchronized éè¿è¡æ¯è¾ï¼è½ç¶å®åéé½å
·æå¯è§æ§ï¼ä½æ¯ volatile ä¸å
·æååæ§ï¼å®ä¸æ¯çæ£æä¹ä¸å
·æçº¿ç¨å®å
¨æ§çä¸ç§å·¥å
·ã
ä»ç¨åºä»£ç ç®ææ§åå¯ä¼¸ç¼©æ§è§åº¦æ¥çï¼ä½ å¯è½æ´å¾åäºä½¿ç¨ volatile è䏿¯éï¼å 为 volatile åèµ·æ¥æ´æ¹ä¾¿ï¼å¹¶ä¸ volatile ä¸ä¼åé飿 ·é æçº¿ç¨é»å¡ï¼èä¸å¦æç¨åºä¸ç读æä½ç使ç¨è¿è¿å¤§äºåæä½çè¯ï¼volatile ç¸å¯¹äºéè¿æ´å å
·ææ§è½ä¼å¿ã
å¾å¤å¹¶åä¸å®¶é½æ¨èè¿ç¦» volatile åéï¼å 为å®ä»¬ç¸å¯¹äºéæ´å 容æåºéï¼ä½æ¯å¦æä½ è°¨æ
çéµä»ä¸äºæ¨¡å¼ï¼å°±è½å¤å®å
¨çä½¿ç¨ volatile åéï¼è¿éæä¸ä¸ª volatile 使ç¨åå
>**åªæå¨ç¶æçæ£ç¬ç«äºç¨åºå
å
¶ä»å
å®¹æ¶æè½ä½¿ç¨ volatile**ã
ä¸é¢æä»¬éè¿å æ®µä»£ç æ¥æåä¸ä¸è¿æ¡è§åçåéã
### ç¶ææ å¿
ä¸ç§æç®åä½¿ç¨ volatile çæ¹å¼å°±æ¯å° volatile ä½ä¸ºç¶ææ å¿æ¥ä½¿ç¨ã
```java
volatile boolean shutdownRequested;
public void shutdown() { shutdownRequested = true; }
public void doWork() {
while (!shutdownRequested) {
// do stuff
}
}
```
为äºè½å¤æ£ç¡®çè°ç¨ shutdown() æ¹æ³ï¼ä½ éè¦ç¡®ä¿ shutdownRequested çå¯è§æ§ãè¿ç§ç¶ææ å¿çä¸ç§ç¹æ§å°±æ¯éå¸¸åªæä¸ç§ç¶æè½¬æ¢ï¼shutdownRequested çæ å¿ä» false 转为 trueï¼ç¶åç¨åºåæ¢ãè¿ç§æ¨¡å¼å¯ä»¥ç¸äºæ¥å转æ¢ã
### å鿣æ¥é
ä½¿ç¨ volatile å synchronized å¯ä»¥æ»¡è¶³å鿣æ¥éçå便¨¡å¼ã
```java
class Singleton{
private volatile static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null)
instance = new Singleton();
}
}
return instance;
}
}
```
è¿é说ä¸ä¸ºä»ä¹è¦ç¨ä¸¤æ¬¡æ£æ¥ï¼åå¦æä¸¤ä¸ªçº¿ç¨ï¼çº¿ç¨ä¸å¨è¿å
¥å° synchronized 忥代ç åä¹åï¼å¨è¿æ²¡æçæ Singleton 对象ååç线ç¨åæ¢ï¼æ¤æ¶çº¿ç¨äºå¤æ instance == null 为 trueï¼ä¼åç线ç¨åæ¢ï¼åæ¢å°çº¿ç¨ä¸ï¼ç¶åéåºåæ¥ä»£ç åï¼çº¿ç¨åæ¢ï¼çº¿ç¨äºè¿å
¥åæ¥ä»£ç ååï¼ä¼å夿ä¸ä¸ instance çå¼ï¼è¿å°±æ¯å鿣æ¥éçå¿
è¦æå¨ã
### 读-åé
è¿ä¹æ¯ volatile å synchronized ä¸èµ·ä½¿ç¨ç示ä¾ï¼ç¨äºå®ç°å¼éæ¯è¾ä½ç读-åéã
```java
public class ReadWriteLockTest {
private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
```
妿åªä½¿ç¨ volatile æ¯ä¸è½å®å
¨å®ç°è®¡æ°å¨çï¼ä½æ¯ä½ è½å¤å¨è¯»æä½ä¸ä½¿ç¨ volatile ä¿è¯å¯è§æ§ãå¦æä½ æ³è¦å®ç°ä¸ç§è¯»åéçè¯ï¼å¿
é¡»è¿è¡å¤é¨å éã

