# Java å¤çº¿ç¨ä¸å¤§æ ¸å¿ ## ååæ§ `Java` çå忧就忰æ®åºäºç©çååæ§å·®ä¸å¤ï¼ä¸ä¸ªæä½ä¸è¦ä¹å ¨é¨æ§è¡æåæè 失败ã `JMM` åªæ¯ä¿è¯äºåºæ¬çååæ§ï¼ä½ç±»ä¼¼äº `i++` ä¹ç±»çæä½ï¼çä¼¼æ¯ååæä½ï¼å ¶å®é颿¶åå°: - è·å i çå¼ã - èªå¢ã - åèµå¼ç» iã è¿ä¸æ¥æä½ï¼æä»¥æ³è¦å®ç° `i++` è¿æ ·çååæä½å°±éè¦ç¨å° `synchronize` æè æ¯ `lock` è¿è¡å éå¤çã 妿æ¯åºç¡ç±»çèªå¢æä½å¯ä»¥ä½¿ç¨ `AtomicInteger` è¿æ ·çååç±»æ¥å®ç°(å ¶æ¬è´¨æ¯å©ç¨äº `CPU` 级å«ç ç `CAS` æä»¤æ¥å®æç)ã å ¶ä¸ç¨çæå¤çæ¹æ³å°±æ¯: `incrementAndGet()` 以ååçæ¹å¼èªå¢ã æºç å¦ä¸: ```java public final long incrementAndGet() { for (;;) { long current = get(); long next = current + 1; if (compareAndSet(current, next)) return next; } } ``` é¦å æ¯è·å¾å½åçå¼ï¼ç¶åèªå¢ +1ãæ¥çåæ¯ææ ¸å¿ç `compareAndSet() ` æ¥è¿è¡ååæ´æ°ã ```java public final boolean compareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); } ``` å ¶é»è¾å°±æ¯å¤æå½åç弿¯å¦è¢«æ´æ°è¿ï¼æ¯å¦çäº `current`ï¼å¦æçäºå°±è¯´ææ²¡ææ´æ°è¿ç¶åå°å½åç弿´æ°ä¸º `next`ï¼å¦æä¸çäºåè¿å`false` è¿å ¥å¾ªç¯ï¼ç´å°æ´æ°æå为æ¢ã è¿æå ¶ä¸ç `get()` æ¹æ³ä¹å¾å ³é®ï¼è¿åçæ¯å½åçå¼ï¼å½åå¼ç¨äº `volatile` å ³é®è¯ä¿®é¥°ï¼ä¿è¯äºå åå¯è§æ§ã ```java private volatile int value; ``` ## å¯è§æ§ ç°ä»£è®¡ç®æºä¸ï¼ç±äº `CPU` ç´æ¥ä»ä¸»å åä¸è¯»åæ°æ®çæçä¸é«ï¼æä»¥é½ä¼å¯¹åºç `CPU` é«éç¼åï¼å å°ä¸»å åä¸çæ°æ®è¯»åå°ç¼åä¸ï¼çº¿ç¨ä¿®æ¹æ°æ®ä¹åé¦å æ´æ°å°ç¼åï¼ä¹åæä¼æ´æ°å°ä¸»å åãå¦ææ¤æ¶è¿æ²¡æå°æ°æ®æ´æ°å°ä¸»å åå ¶ä»ççº¿ç¨æ¤æ¶æ¥è¯»åå°±æ¯ä¿®æ¹ä¹åçæ°æ®ã  å¦ä¸å¾æç¤ºã `volatile` å ³é®åå°±æ¯ç¨äºä¿è¯å åå¯è§æ§ï¼å½çº¿ç¨Aæ´æ°äº volatile 修饰çåéæ¶ï¼å®ä¼ç«å³å·æ°å°ä¸»çº¿ç¨ï¼å¹¶ä¸å°å ¶ä½ç¼åä¸è¯¥åéç弿¸ 空ï¼å¯¼è´å ¶ä½çº¿ç¨åªè½å»ä¸»å åè¯»åææ°å¼ã ä½¿ç¨ `volatile` å ³é®è¯ä¿®é¥°çåéæ¯æ¬¡è¯»åé½ä¼å¾å°ææ°çæ°æ®ï¼ä¸ç®¡åªä¸ªçº¿ç¨å¯¹è¿ä¸ªåéçä¿®æ¹é½ä¼ç«å³å·æ°å°ä¸»å åã `synchronize`åå éä¹è½è½ä¿è¯å¯è§æ§ï¼å®ç°åçå°±æ¯å¨éæ¾éä¹åå ¶ä½çº¿ç¨æ¯è®¿é®ä¸å°è¿ä¸ªå ±äº«åéçã使¯å `volatile` ç¸æ¯å¼éè¾å¤§ã ## é¡ºåºæ§ 以ä¸è¿æ®µä»£ç : ```java int a = 100 ; //1 int b = 200 ; //2 int c = a + b ; //3 ``` æ£å¸¸æ åµä¸çæ§è¡é¡ºåºåºè¯¥æ¯ `1>>2>>3`ã使¯ææ¶ `JVM` ä¸ºäºæé«æ´ä½çæçä¼è¿è¡æä»¤éæå¯¼è´æ§è¡ç顺åºå¯è½æ¯ `2>>1>>3`ã使¯ `JVM` ä¹ä¸è½æ¯ä»ä¹é½è¿è¡éæï¼æ¯å¨ä¿è¯æç»ç»æå代ç é¡ºåºæ§è¡ç»æä¸è´çæ åµä¸æå¯è½è¿è¡éæã éæå¨å线ç¨ä¸ä¸ä¼åºç°é®é¢ï¼ä½å¨å¤çº¿ç¨ä¸ä¼åºç°æ°æ®ä¸ä¸è´çé®é¢ã Java ä¸å¯ä»¥ä½¿ç¨ `volatile` æ¥ä¿è¯é¡ºåºæ§ï¼`synchronize å lock` ä¹å¯ä»¥æ¥ä¿è¯æåºæ§ï¼åä¿è¯ååæ§çæ¹å¼ä¸æ ·ï¼éè¿å䏿®µæ¶é´åªè½ä¸ä¸ªçº¿ç¨è®¿é®æ¥å®ç°çã é¤äºéè¿ `volatile` å ³é®åæ¾å¼çä¿è¯é¡ºåºä¹å¤ï¼ `JVM` è¿éè¿ `happen-before` å忥éå¼çä¿è¯é¡ºåºæ§ã å ¶ä¸æä¸æ¡å°±æ¯éç¨äº `volatile` å ³é®åçï¼éå¯¹äº `volatile` å ³é®åçåæä½è¯å®æ¯å¨è¯»æä½ä¹åï¼ä¹å°±æ¯è¯´è¯»åçå¼è¯å®æ¯ææ°çã ### volatile çåºç¨ #### å鿣æ¥éçå便¨¡å¼ å¯ä»¥ç¨ `volatile` å®ç°ä¸ä¸ªå鿣æ¥éçå便¨¡å¼ï¼ ```java public class Singleton{ private static volatile Singleton singleton ; private Singleton(){} public static Singleton getInstance(){ if(singleton == null){ synchronize(Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } } return singleton ; } } ``` è¿éç `volatile` å ³é®åä¸»è¦æ¯ä¸ºäºé²æ¢æä»¤éæã 妿ä¸ç¨ `volatile` ï¼`singleton = new Singleton();`ï¼è¿æ®µä»£ç å ¶å®æ¯åä¸ºä¸æ¥ï¼ - åé å å空é´ã(1) - åå§å对象ã(2) - å° `singleton` 对象æååé çå åå°åã(3) å ä¸ `volatile` æ¯ä¸ºäºè®©ä»¥ä¸ç䏿¥æä½é¡ºåºæ§è¡ï¼å乿å¯è½ç¬¬äºæ¥å¨ç¬¬ä¸æ¥ä¹å被æ§è¡å°±æå¯è½æä¸ªçº¿ç¨æ¿å°çåä¾å¯¹è±¡æ¯è¿æ²¡æåå§åçï¼ä»¥è´äºæ¥éã #### æ§å¶åæ¢çº¿ç¨çæ è®° ```java private volatile boolean flag ; private void run(){ new Thread(new Runnable(){ if(flag){ doSomeThing(); } }); } private void stop(){ flag = false ; } ``` è¿éå¦ææ²¡æç¨ volatile æ¥ä¿®é¥° flag ï¼å°±æå¯è½å ¶ä¸ä¸ä¸ªçº¿ç¨è°ç¨äº `stop()`æ¹æ³ä¿®æ¹äº flag çå¼å¹¶ä¸ä¼ç«å³å·æ°å°ä¸»å åä¸ï¼å¯¼è´è¿ä¸ªå¾ªç¯å¹¶ä¸ä¼ç«å³åæ¢ã è¿é主è¦å©ç¨çæ¯ `volatile` çå åå¯è§æ§ã æ»ç»ä¸ä¸: - `volatile` å ³é®ååªè½ä¿è¯å¯è§æ§ï¼é¡ºåºæ§ï¼**ä¸è½ä¿è¯ååæ§**ã