一、并發(fā)編程特性
1、原子性:一個操作要么成功要么失敗,中間不會中斷
2、可見性:多個線程同時訪問某個變量,當(dāng)變量發(fā)生修改,其他線程可以立即看到被修改的值
3、有序性:代碼按照代碼的先后順序執(zhí)行
二、volatile可見性原理
volatile保證了可見性和有序性,可以有效的防止指令重排;
導(dǎo)致程序可見性問題,主要是因?yàn)楫?dāng)線程工作時,需要先把主內(nèi)存中的變量拷貝(Load)到工作內(nèi)存中,執(zhí)行完成后,再寫回(Store)到主內(nèi)存中;所以這個中間就會存在多線程復(fù)寫的問題;

當(dāng)加了volatile關(guān)鍵字,則通過"內(nèi)存屏障"來防止指令重排;
1. lfence,是一種Load Barrier 讀屏障
2. sfence, 是一種Store Barrier 寫屏障
3. mfence, 是一種全能型的屏障,具備ifence和sfence的能力
4. Lock前綴,Lock不是一種內(nèi)存屏障,但是它能完成類似內(nèi)存屏障的功能。Lock會對CPU總線和高速緩存加鎖,可以理解為CPU指令級的一種鎖。它后面可以跟ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG等指令。
JVM提供的內(nèi)存屏障:LoadLoad,StoreStore,LoadStore,StoreLoad;
可見性主要是通過MESI(修改 Modified? 獨(dú)享 Exclusive 共享Shared 無效 Invalid)機(jī)制來保證可見性;通過字節(jié)碼可以看到,被volatile修飾的變量會有ACC_VOLATILE訪問標(biāo)識,通過匯編可以看到,執(zhí)行時會lock

不同的硬件架構(gòu)對MESI的實(shí)現(xiàn)不一樣,一般CPU的三級緩存架構(gòu),讀取緩存行(64byte)到cpu緩存,然后該CPU通過bus總線監(jiān)控是否還有其他CPU讀取該變量,通知也是通過總線通知;如果同時有其他線程對該變量進(jìn)行修改,則會進(jìn)行總線裁決;