当前位置: 首页>后端>正文

volatile底层原理

涓€銆丣MM

JMM 鍗?Java Memory Model锛屽畠瀹氫箟浜嗕富瀛樸€佸伐浣滃唴瀛樻娊璞℃蹇碉紝搴曞眰瀵瑰簲鐫€ CPU 瀵勫瓨鍣ㄣ€佺紦瀛樸€佺‖浠跺唴瀛樸€丆PU 鎸囦护浼樺寲绛夈€?br> JMM 浣撶幇鍦ㄤ互涓嬪嚑涓柟闈?/p>

  • 鍘熷瓙鎬?- 淇濊瘉鎸囦护涓嶄細鍙楀埌绾跨▼涓婁笅鏂囧垏鎹㈢殑褰卞搷
  • 鍙鎬?- 淇濊瘉鎸囦护涓嶄細鍙?cpu 缂撳瓨鐨勫奖鍝?/li>
  • 鏈夊簭鎬?- 淇濊瘉鎸囦护涓嶄細鍙?cpu 鎸囦护骞惰浼樺寲鐨勫奖鍝?/li>

涓诲瓨瀵瑰簲鍫嗗唴瀛橈紝宸ヤ綔鍐呭瓨瀵瑰簲鏍堝唴瀛橈紝绾跨▼闇€瑕佷粠涓诲瓨璇绘暟鎹紝鐒跺悗鍦ㄥ伐浣滃唴瀛樹腑璁$畻锛屾渶鍚庡啓鍥炰富瀛樸€?/p>

浜屻€佸彲瑙佹€?/h2>
@Slf4j
public class TestVisible {
    static boolean runFlag = true;
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (runFlag){

            }
            log.debug("鍋滄寰幆浜?);
        });
        t.start();

        Thread.sleep(1000);
        log.debug("鍋滄t1");
        runFlag = false;
    }
}
17:28:19.008 [main] DEBUG juc.visibility.TestVisible - 鍋滄t1

1.鍒濆鐘舵€侊紝 t 绾跨▼鍒氬紑濮嬩粠涓诲唴瀛樿鍙栦簡 run 鐨勫€煎埌宸ヤ綔鍐呭瓨


volatile底层原理,第1张

2.鍥犱负 t 绾跨▼瑕侀绻佷粠涓诲唴瀛樹腑璇诲彇 run 鐨勫€硷紝JIT 缂栬瘧鍣ㄤ細灏?run 鐨勫€肩紦瀛樿嚦鑷繁宸ヤ綔鍐呭瓨涓殑楂橀€熺紦瀛樹腑锛屽噺灏戝涓诲瓨涓?run 鐨勮闂紝鎻愰珮鏁堢巼


volatile底层原理,第2张

3.1 绉掍箣鍚庯紝main 绾跨▼淇敼浜?run 鐨勫€硷紝骞跺悓姝ヨ嚦涓诲瓨锛岃€?t 鏄粠鑷繁宸ヤ綔鍐呭瓨涓殑楂橀€熺紦瀛樹腑璇诲彇杩欎釜鍙橀噺鐨勫€硷紝缁撴灉姘歌繙鏄棫鍊?/p>

volatile底层原理,第3张

瑙e喅鏂瑰紡涓€锛歷olatile(鎺ㄨ崘)
volatile锛氬畠鍙互鐢ㄦ潵淇グ鎴愬憳鍙橀噺鍜岄潤鎬佹垚鍛樺彉閲忥紝鍙互閬垮厤绾跨▼浠庤嚜宸辩殑宸ヤ綔缂撳瓨涓煡鎵惧彉閲忕殑鍊硷紝蹇呴』鍒颁富瀛樹腑鑾峰彇瀹冪殑鍊硷紝绾跨▼鎿嶄綔 volatile 鍙橀噺閮芥槸鐩存帴鎿嶄綔涓诲瓨銆?/p>

@Slf4j
public class TestVisible {
    static volatile boolean runFlag = true;
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (runFlag){

            }
            log.debug("鍋滄寰幆浜?);
        });
        t.start();

        Thread.sleep(1000);
        log.debug("鍋滄t1");
        runFlag = false;
    }
}
18:33:39.386 [main] DEBUG juc.visibility.TestVisible - 鍋滄t1
18:33:39.389 [Thread-0] DEBUG juc.visibility.TestVisible - 鍋滄寰幆浜?

瑙e喅鏂瑰紡浜岋細synchronized

@Slf4j
public class TestVisible1 {
    static boolean runFlag = true;
    final static Object lock = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (true){
                synchronized (lock){
                    if(!runFlag){
                        break;
                    }
                }
            }
            log.debug("鍋滄寰幆浜?);
        });
        t.start();

        Thread.sleep(1000);
        log.debug("鍋滄t1");
        synchronized (lock){
            runFlag = false;
        }
    }
}

绾跨▼杩涘叆synchronized浠g爜鍓嶏紝浼氳幏寰楅攣锛屾竻绌哄伐浣滃唴瀛橈紝浠庝富鍐呭瓨鎷疯礉鍏变韩鍙橀噺鏈€鏂扮殑鍊煎埌宸ヤ綔鍐呭瓨鎴愪负鍓湰锛屾墽琛屼唬鐮侊紝灏嗕慨鏀瑰悗鐨勫壇鏈€煎埛鏂板洖涓诲唴瀛樹腑锛岄噴鏀鹃攣銆?/p>

鍙鎬?vs 鍘熷瓙鎬?/h4>

鍙鎬т繚璇佺殑鏄湪澶氫釜绾跨▼涔嬮棿锛屼竴涓嚎绋嬪 volatile 鍙橀噺鐨勪慨鏀瑰鍙︿竴涓嚎绋嬪彲瑙侊紝 浣嗕笉鑳戒繚璇佸師瀛愭€э紝浠呯敤鍦ㄤ竴涓啓绾跨▼锛屽涓绾跨▼鐨勬儏鍐碉細
涓婁緥浠庡瓧鑺傜爜鐞嗚В鏄繖鏍风殑锛?/p>

getstatic run // 绾跨▼ t 鑾峰彇 run true
getstatic run // 绾跨▼ t 鑾峰彇 run true
getstatic run // 绾跨▼ t 鑾峰彇 run true
getstatic run // 绾跨▼ t 鑾峰彇 run true
putstatic run // 绾跨▼ main 淇敼 run 涓?false锛?浠呮涓€娆?
getstatic run // 绾跨▼ t 鑾峰彇 run false

涓や釜绾跨▼锛氫竴涓?i++ 涓€涓?i-- 锛屽彧鑳戒繚璇佺湅鍒版渶鏂板€硷紝涓嶈兘瑙e喅鎸囦护浜ら敊鐨勫師瀛愭€ч棶棰橈細

// 鍋囪i鐨勫垵濮嬪€间负0
getstatic i // 绾跨▼2-鑾峰彇闈欐€佸彉閲廼鐨勫€?绾跨▼鍐卛=0

getstatic i // 绾跨▼1-鑾峰彇闈欐€佸彉閲廼鐨勫€?绾跨▼鍐卛=0
iconst_1 // 绾跨▼1-鍑嗗甯搁噺1
iadd // 绾跨▼1-鑷 绾跨▼鍐卛=1
putstatic i // 绾跨▼1-灏嗕慨鏀瑰悗鐨勫€煎瓨鍏ラ潤鎬佸彉閲廼 闈欐€佸彉閲廼=1

iconst_1 // 绾跨▼2-鍑嗗甯搁噺1
isub // 绾跨▼2-鑷噺 绾跨▼鍐卛=-1
putstatic i // 绾跨▼2-灏嗕慨鏀瑰悗鐨勫€煎瓨鍏ラ潤鎬佸彉閲廼 闈欐€佸彉閲廼=-1

synchronized 璇彞鍧楁棦鍙互淇濊瘉浠g爜鍧楃殑鍘熷瓙鎬э紝涔熷悓鏃朵繚璇佷唬鐮佸潡鍐呭彉閲忕殑鍙鎬с€備絾缂虹偣鏄痵ynchronized 鏄睘浜庨噸閲忕骇鎿嶄綔锛屾€ц兘鐩稿鏇翠綆

涓夈€乿olatile搴旂敤

浣跨敤volatile鏀硅繘涓ら樁娈电粓姝細

@Slf4j
public class TestVolatile {

    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTerminate twoPhaseTerminate = new TwoPhaseTerminate();
        twoPhaseTerminate.start();
        Thread.sleep(4000);
        twoPhaseTerminate.stop();
    }
}

@Slf4j
class TwoPhaseTerminate {

    private Thread monitorThread;

    private volatile boolean stopFlag = false;

    /**
     * 鍚姩绾跨▼
     */
    public void start() {
        monitorThread = new Thread(() -> {
            while (true) {
                // 鏄惁琚墦鏂?
                if (stopFlag) {
                    log.debug("鏂欑悊鍚庝簨");
                    break;
                }
                try {
                    Thread.sleep(1000);
                    log.debug("鎵ц鐩戞帶璁板綍");
                } catch (InterruptedException e) {
                    //涓嶉渶瑕佽€冭檻鎵撴柇鏍囪锛屽洜涓轰娇鐢ㄧ殑鏄痵topFlag鏉ユ帶鍒剁殑
                    e.printStackTrace();
                }
            }
        }, "monitor");
        monitorThread.start();
    }

    /**
     * 鍋滄绾跨▼
     */
    public void stop() {
        stopFlag = true;
        //闃叉绾跨▼鍒氬ソ鍦ㄦ墽琛宻leep鐨勮繃绋嬩腑琚仠姝紝鐢╥nterrupt鏉ョ粓姝leep
        monitorThread.interrupt();
    }
}

19:31:36.199 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鎵ц鐩戞帶璁板綍
19:31:37.205 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鎵ц鐩戞帶璁板綍
19:31:38.206 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鎵ц鐩戞帶璁板綍
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at juc.visibility.TwoPhaseTerminate.lambda$start

鍥涖€佸悓姝ユā寮忎箣Balking

(TestVolatile.java:43) at java.lang.Thread.run(Thread.java:748) 19:31:39.195 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鏂欑悊鍚庝簨
@Slf4j public class TestVolatile { public static void main(String[] args) throws InterruptedException { TwoPhaseTerminate twoPhaseTerminate = new TwoPhaseTerminate(); twoPhaseTerminate.start(); twoPhaseTerminate.start(); twoPhaseTerminate.start(); Thread.sleep(4000); twoPhaseTerminate.stop(); } } @Slf4j class TwoPhaseTerminate { private Thread monitorThread; private volatile boolean stopFlag = false; /** * 鐢ㄤ竴涓爣璁颁綅鏉ユ爣璁板彧闇€瑕佹墽琛屼竴閬嶇殑浠g爜涓嶉噸澶嶆墽琛? */ private boolean startFlag = false; /** * 鍚姩绾跨▼ */ public void start() { synchronized (this) { if (startFlag) { return; } startFlag = true; } monitorThread = new Thread(() -> { while (true) { // 鏄惁琚墦鏂? if (stopFlag) { log.debug("鏂欑悊鍚庝簨"); break; } try { Thread.sleep(1000); log.debug("鎵ц鐩戞帶璁板綍"); } catch (InterruptedException e) { //涓嶉渶瑕佽€冭檻鎵撴柇鏍囪锛屽洜涓轰娇鐢ㄧ殑鏄痵topFlag鏉ユ帶鍒剁殑 e.printStackTrace(); } } }, "monitor"); monitorThread.start(); } /** * 鍋滄绾跨▼ */ public void stop() { stopFlag = true; //闃叉绾跨▼鍒氬ソ鍦ㄦ墽琛宻leep鐨勮繃绋嬩腑琚仠姝紝鐢╥nterrupt鏉ョ粓姝leep monitorThread.interrupt(); } }

Balking锛堢姽璞級妯″紡鐢ㄥ湪涓€涓嚎绋嬪彂鐜板彟涓€涓嚎绋嬫垨鏈嚎绋嬪凡缁忓仛浜嗘煇涓€浠剁浉鍚岀殑浜嬶紝閭d箞鏈嚎绋嬪氨鏃犻渶鍐嶅仛浜嗭紝鐩存帴缁撴潫杩斿洖銆傪煓凁煓凁煓?br> demo1:

19:54:17.437 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鎵ц鐩戞帶璁板綍
19:54:18.441 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鎵ц鐩戞帶璁板綍
19:54:19.443 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鎵ц鐩戞帶璁板綍
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at juc.visibility.TwoPhaseTerminate.lambda$startpublic class Singleton {

    private static Singleton INSTANCE = null;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (INSTANCE != null) {
            return INSTANCE;
        }
        return new Singleton();
    }
}
(TestVolatile.java:55)
    at java.lang.Thread.run(Thread.java:748)
19:54:20.432 [monitor] DEBUG juc.visibility.TwoPhaseTerminate - 鏂欑悊鍚庝簨
鍙栨寚浠?- 鎸囦护璇戠爜 - 鎵ц鎸囦护 - 鍐呭瓨璁块棶 - 鏁版嵁鍐欏洖

demo2:

// 鍙互閲嶆帓鐨勪緥瀛?
int a = 10; // 鎸囦护1
int b = 20; // 鎸囦护2
System.out.println( a + b );
// 涓嶈兘閲嶆帓鐨勪緥瀛?
int a = 10; // 鎸囦护1
int b = a - 5; // 鎸囦护2

浜斻€佹湁搴忔€?/h2>

1.鎸囦护閲嶆帓搴忎紭鍖?/h4>

鐜颁唬澶勭悊鍣ㄤ細璁捐涓轰竴涓椂閽熷懆鏈熷畬鎴愪竴鏉℃墽琛屾椂闂存渶闀跨殑 CPU 鎸囦护锛?br> 鎸囦护鍙互鍐嶅垝鍒嗘垚涓€涓釜鏇村皬鐨勯樁娈碉紝渚嬪锛屾瘡鏉℃寚浠ら兘鍙互鍒嗕负锛?br>

3.鍐呭瓨灞忛殰

杩?5 涓樁娈点€?/p>

鍦ㄤ笉鏀瑰彉绋嬪簭缁撴灉鐨勫墠鎻愪笅锛岃繖浜涙寚浠ょ殑鍚勪釜闃舵鍙互閫氳繃閲嶆帓搴忓拰缁勫悎鏉ュ疄鐜版寚浠ょ骇骞惰锛岃繖涓€鎶€鏈湪 80's 涓彾鍒?90's 涓彾鍗犳嵁浜嗚绠楁灦鏋勭殑閲嶈鍦颁綅銆?/p>

鎸囦护閲嶆帓鐨勫墠鎻愭槸锛岄噸鎺掓寚浠や笉鑳藉奖鍝嶇粨鏋滐紝渚嬪

  • 鍐欏睆闅滐紙sfence锛変繚璇佸湪璇ュ睆闅滀箣鍓嶇殑锛屽鍏变韩鍙橀噺鐨勬敼鍔紝閮藉悓姝ュ埌涓诲瓨褰撲腑
  • 2.鏀寔娴佹按绾跨殑澶勭悊鍣?/h4>

    鐜颁唬 CPU 鏀寔澶氱骇鎸囦护娴佹按绾匡紝渚嬪鏀寔鍚屾椂鎵ц 鍙栨寚浠?- 鎸囦护璇戠爜 - 鎵ц鎸囦护 - 鍐呭瓨璁块棶 - 鏁版嵁鍐欏洖 鐨勫鐞嗗櫒锛屽氨鍙互绉颁箣涓轰簲绾ф寚浠ゆ祦姘寸嚎銆傝繖鏃?CPU 鍙互鍦ㄤ竴涓椂閽熷懆鏈熷唴锛屽悓鏃惰繍琛屼簲鏉℃寚浠ょ殑涓嶅悓闃舵锛堢浉褰撲簬涓€鏉℃墽琛屾椂闂存渶闀跨殑澶嶆潅鎸囦护锛夛紝IPC = 1锛屾湰璐ㄤ笂锛屾祦姘寸嚎鎶€鏈苟涓嶈兘缂╃煭鍗曟潯鎸囦护鐨勬墽琛屾椂闂达紝浣嗗畠鍙樼浉鍦版彁楂樹簡鎸囦护鍦板悶鍚愮巼銆?/p>

    鍏€乿olatile 鍘熺悊

    Memory Barrier锛圡emory Fence锛?/p>

    鍙鎬?/strong>锛?/p>

      private volatile boolean ready = false; public void test(Result r) { //num鏄櫘閫氬彉閲忥紝涔熶細琚悓姝ュ埌涓诲瓨 num = 2; // ready 鏄?volatile 锛岃祴鍊煎甫鍐欏睆闅? ready = true; // 鍐欏睆闅? }
    • 璇诲睆闅滐紙lfence锛変繚璇佸湪璇ュ睆闅滀箣鍚庯紝瀵瑰叡浜彉閲忕殑璇诲彇锛屽姞杞界殑鏄富瀛樹腑鏈€鏂版暟鎹?/li>

    鏈夊簭鎬?/strong>:

    • 鍐欏睆闅滀細纭繚鎸囦护閲嶆帓搴忔椂锛屼笉浼氬皢鍐欏睆闅滀箣鍓嶇殑浠g爜鎺掑湪鍐欏睆闅滀箣鍚?/li>
    • 璇诲睆闅滀細纭繚鎸囦护閲嶆帓搴忔椂锛屼笉浼氬皢璇诲睆闅滀箣鍚庣殑浠g爜鎺掑湪璇诲睆闅滀箣鍓?/li>
    private volatile boolean ready = false; public void test(Result r) { // 璇诲睆闅? // ready 鏄?volatile 璇诲彇鍊硷紝甯﹁灞忛殰 if(ready) { r.r1 = num + num; } else { r.r1 = 1; } }

    volatile 鐨勫簳灞傚疄鐜板師鐞嗘槸鍐呭瓨灞忛殰锛歁emory Barrier锛圡emory Fence锛?/p>

    • 瀵?volatile 鍙橀噺鐨勫啓鎸囦护鍚庝細鍔犲叆鍐欏睆闅?/li>
    • 瀵?volatile 鍙橀噺鐨勮鎸囦护鍓嶄細鍔犲叆璇诲睆闅?/li>

    1.淇濊瘉鍙鎬?/h4>

    鍐欏睆闅滐紙sfence锛夛細淇濊瘉鍦ㄨ灞忛殰涔嬪墠鐨勶紝瀵瑰叡浜彉閲忕殑鏀瑰姩锛堜笉鍙槸volatile淇グ鐨勶級锛岄兘鍚屾鍒颁富瀛樺綋涓細

    public void test(Result r) {
      num = 2;
      // ready 鏄?volatile锛?璧嬪€煎甫鍐欏睆闅?
      ready = true; 
      // 鍐欏睆闅?
    }
    

    璇诲睆闅滐紙lfence锛夛細淇濊瘉鍦ㄨ灞忛殰涔嬪悗锛屽鍏变韩鍙橀噺鐨勮鍙栵紝鍔犺浇鐨勬槸涓诲瓨涓渶鏂版暟鎹細

    public void test(Result r) {
      // 璇诲睆闅?
      // ready 鏄?volatile锛?璇诲彇鍊煎甫璇诲睆闅?
      if(ready) {
        r.r1 = num + num;
      } else {
        r.r1 = 1;
      }
    }
    
    volatile底层原理,第4张

    鍐欏睆闅滀箣鍓嶇殑閮藉啓杩涗富瀛橈紝璇诲睆闅滀箣鍚庣殑閮戒粠涓诲瓨璇汇€?/p>

    2.淇濊瘉鏈夊簭鎬?/h4>

    鍐欏睆闅滐細纭繚鎸囦护閲嶆帓搴忔椂锛屼笉浼氬皢鍐欏睆闅滀箣鍓嶇殑浠g爜鎺掑湪鍐欏睆闅滀箣鍚?/p>

    涓冦€乨ouble-checked lock

    璇诲睆闅滐細纭繚鎸囦护閲嶆帓搴忔椂锛屼笉浼氬皢璇诲睆闅滀箣鍚庣殑浠g爜鎺掑湪璇诲睆闅滀箣鍓?/p>

    public final class Singleton {
        private Singleton() { }
        private static Singleton INSTANCE = null;
        public static Singleton getInstance() {
            if(INSTANCE == null) {
                synchronized(Singleton.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new Singleton();
                    }
                }
            }
            return INSTANCE;
        }
    }
    

    3.淇濊瘉涓嶄簡鍘熷瓙鎬?/h4>

    涓嶈兘瑙e喅鎸囦护浜ら敊锛?/p>

    • 鍐欏睆闅滀粎浠呮槸淇濊瘉涔嬪悗鐨勮鑳藉璇诲埌鏈€鏂扮殑缁撴灉锛屼絾涓嶈兘淇濊瘉璇昏窇鍒板畠鍓嶉潰鍘?/li>
    • 鏈夊簭鎬х殑淇濊瘉涔熷彧鏄繚璇佷簡鏈嚎绋嬪唴鐩稿叧浠g爜涓嶈閲嶆帓搴?/li>
    0: getstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 3: ifnonnull 37 6: ldc #3 // class juc/visibility/Singleton 8: dup 9: astore_0 10: monitorenter 11: getstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 14: ifnonnull 27 17: new #4 // class juc/visibility/DCLSingleton 20: dup 21: invokespecial #5 // Method "<init>":()V 24: putstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 27: aload_0 28: monitorexit 29: goto 37 32: astore_1 33: aload_0 34: monitorexit 35: aload_1 36: athrow 37: getstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 40: areturn Exception table:
  • 17 琛ㄧず鍒涘缓瀵硅薄锛屽皢瀵硅薄寮曠敤鍏ユ爤 // new Singleton
  • 浠ヤ笂鍗曚緥妯″紡瀛樺湪鐨勯棶棰橈細
    getInstance 鏂规硶瀵瑰簲鐨勫瓧鑺傜爜涓?/p>

  • 20 琛ㄧず澶嶅埗涓€浠藉璞″紩鐢?// 寮曠敤鍦板潃
  • 鍏朵腑

    • 24 琛ㄧず鍒╃敤涓€涓璞″紩鐢紝璧嬪€肩粰 static INSTANCE
    • public class DCLSingleton { private DCLSingleton() { } private static volatile DCLSingleton INSTANCE = null; public static DCLSingleton getInstance() { if(INSTANCE == null) { synchronized(Singleton.class) { if (INSTANCE == null) { INSTANCE = new DCLSingleton(); } } } return INSTANCE; } }
    • 21 琛ㄧず鍒╃敤涓€涓璞″紩鐢紝璋冪敤鏋勯€犳柟娉?/li> 0: getstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 3: ifnonnull 37 6: ldc #3 // class juc/visibility/Singleton 8: dup 9: astore_0 10: monitorenter //-----------------------> 淇濊瘉鍘熷瓙鎬с€佸彲瑙佹€? 11: getstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 14: ifnonnull 27 17: new #4 // class juc/visibility/DCLSingleton 20: dup 21: invokespecial #5 // Method "<init>":()V 24: putstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; // -------------------------------------> 鍔犲叆瀵?INSTANCE 鍙橀噺鐨勫啓灞忛殰 27: aload_0 28: monitorexit //------------------------> 淇濊瘉鍘熷瓙鎬с€佸彲瑙佹€? 29: goto 37 32: astore_1 33: aload_0 34: monitorexit 35: aload_1 36: athrow 37: getstatic #2 // Field INSTANCE:Ljuc/visibility/DCLSingleton; 40: areturn

    涔熻 jvm 浼氫紭鍖栦负锛氬厛鎵ц 24锛屽啀鎵ц 21銆傚鏋滀袱涓嚎绋?t1锛宼2 鎸夊涓嬫椂闂村簭鍒楁墽琛岋細


    volatile底层原理,第5张

    0: getstatic 杩欒浠g爜鍦?monitor 鎺у埗涔嬪锛屽彲浠ヨ秺杩?monitor 璇诲彇INSTANCE 鍙橀噺鐨勫€硷紝杩欐椂 t1 杩樻湭瀹屽叏灏嗘瀯閫犳柟娉曟墽琛屽畬姣曪紝濡傛灉鍦ㄦ瀯閫犳柟娉曚腑瑕佹墽琛屽緢澶氬垵濮嬪寲鎿嶄綔锛岄偅涔?t2 鎷垮埌鐨勬槸灏嗘槸涓€涓湭鍒濆鍖栧畬姣曠殑鍗曚緥銆?/p>

    瑙e喅锛?br> 瀵?INSTANCE 浣跨敤 volatile 淇グ鍗冲彲锛屽彲浠ョ鐢ㄦ寚浠ら噸鎺掞紝浣嗚娉ㄦ剰鍦?JDK 5 浠ヤ笂鐨勭増鏈殑 volatile 鎵嶄細鐪熸鏈夋晥锛?/p>

    鍏€乭appens-before

    static int x;
    static Object m = new Object();
    new Thread(() -> {
        synchronized (m) {
            x = 10;
        }
    }, "t1").start();
    new Thread(() ->{
        synchronized (m) {
            System.out.println(x);
        }
    }, "t2").start();
    

    璇诲啓 volatile 鍙橀噺鏃朵細鍔犲叆鍐呭瓨灞忛殰锛圡emory Barrier锛圡emory Fence锛夛級锛屼繚璇佷笅闈袱鐐癸細

    • 鍙鎬?br> 鍐欏睆闅滐紙sfence锛変繚璇佸湪璇ュ睆闅滀箣鍓嶇殑 t1 瀵瑰叡浜彉閲忕殑鏀瑰姩锛岄兘鍚屾鍒颁富瀛樺綋涓?br> 璇诲睆闅滐紙lfence锛変繚璇佸湪璇ュ睆闅滀箣鍚?t2 瀵瑰叡浜彉閲忕殑璇诲彇锛屽姞杞界殑鏄富瀛樹腑鏈€鏂版暟鎹?/li>
    • 鏈夊簭鎬?br> 鍐欏睆闅滀細纭繚鎸囦护閲嶆帓搴忔椂锛屼笉浼氬皢鍐欏睆闅滀箣鍓嶇殑浠g爜鎺掑湪鍐欏睆闅滀箣鍚?br> 璇诲睆闅滀細纭繚鎸囦护閲嶆帓搴忔椂锛屼笉浼氬皢璇诲睆闅滀箣鍚庣殑浠g爜鎺掑湪璇诲睆闅滀箣鍓?/p>

      volatile底层原理,第6张

    鏇村簳灞傛槸璇诲啓鍙橀噺鏃朵娇鐢?lock 鎸囦护鏉ュ疄鐜板鏍?CPU 涔嬮棿鐨勫彲瑙佹€т笌鏈夊簭鎬?/p> 2.绾跨▼瀵?volatile 鍙橀噺鐨勫啓锛屽鎺ヤ笅鏉ュ叾瀹冪嚎绋嬪璇ュ彉閲忕殑璇诲彲瑙侊細

    happens-before 瑙勫畾浜嗗鍏变韩鍙橀噺鐨勫啓鎿嶄綔瀵瑰叾瀹冪嚎绋嬬殑璇绘搷浣滃彲瑙侊紝瀹冩槸鍙鎬т笌鏈夊簭鎬х殑涓€濂楄鍒欐€荤粨
    鎶涘紑浠ヤ笅 happens-before 瑙勫垯锛孞MM 骞朵笉鑳戒繚璇佷竴涓嚎绋嬪鍏变韩鍙橀噺鐨勫啓锛屽浜庡叾瀹冪嚎绋嬪璇ュ叡浜彉閲忕殑璇诲彲瑙?/p>

    1.绾跨▼瑙i攣 m 涔嬪墠瀵瑰彉閲忕殑鍐欙紝瀵逛簬鎺ヤ笅鏉ュ m 鍔犻攣鐨勫叾瀹冪嚎绋嬪璇ュ彉閲忕殑璇诲彲瑙?/strong>锛?/p>

    volatile static int x;
    new Thread(()->{
        x = 10;
    },"t1").start();
    new Thread(()->{
        System.out.println(x);
    },"t2").start();
    

    static int x; x = 10; new Thread(()->{ System.out.println(x); },"t2").start();

    4.绾跨▼缁撴潫鍓嶅鍙橀噺鐨勫啓锛屽鍏跺畠绾跨▼寰楃煡瀹冪粨鏉熷悗鐨勮鍙锛堟瘮濡傚叾瀹冪嚎绋嬭皟鐢?t1.isAlive() 鎴?t1.join()绛夊緟瀹冪粨鏉燂級

    3.绾跨▼ start 鍓嶅鍙橀噺鐨勫啓锛屽璇ョ嚎绋嬪紑濮嬪悗瀵硅鍙橀噺鐨勮鍙锛?/strong>

    static int x;
    Thread t1 = new Thread(()->{
        x = 10;
    },"t1");
    t1.start();
    t1.join();
    System.out.println(x);
    

    static int x; public static void main(String[] args) { Thread t2 = new Thread(()->{ while(true) { if(Thread.currentThread().isInterrupted()) { System.out.println(x); break; } } },"t2"); t2.start(); new Thread(()->{ sleep(1); x = 10; t2.interrupt(); },"t1").start(); while(!t2.isInterrupted()) { Thread.yield(); } System.out.println(x); }

    volatile static int x;
    static int y;
    new Thread(()->{
        y = 10;
        x = 20;
    },"t1").start();
    new Thread(()->{
        // x=20 瀵?t2 鍙, 鍚屾椂 y=10 涔熷 t2 鍙
        System.out.println(x);
    },"t2").start();
    

    5.绾跨▼ t1 鎵撴柇 t2锛坕nterrupt锛夊墠瀵瑰彉閲忕殑鍐欙紝瀵逛簬鍏朵粬绾跨▼寰楃煡 t2 琚墦鏂悗瀵瑰彉閲忕殑璇诲彲瑙侊紙閫氳繃t2.interrupted 鎴?t2.isInterrupted锛?/strong>

    
    

    6.瀵瑰彉閲忛粯璁ゅ€硷紙0锛宖alse锛宯ull锛夌殑鍐欙紝瀵瑰叾瀹冪嚎绋嬪璇ュ彉閲忕殑璇诲彲瑙?/strong>

    7.鍏锋湁浼犻€掓€э紝濡傛灉 x hb-> y 骞朵笖 y hb-> z 閭d箞鏈?x hb-> z 锛岄厤鍚?volatile 鐨勯槻鎸囦护閲嶆帓锛屾湁涓嬮潰鐨勪緥瀛?/strong>


    https://www.xamrdz.com/backend/3z31938354.html

    相关文章: