JMM結構圖:
JMM對同步的8種操作:
JMM的同步規則:
Countdownlatch介紹:
該類功能是可以阻塞線程,並在保證線程滿足特定條件下,繼續執行。如上圖,Countdownlatch的cnt初始值是3,線程A調用await()方法,會阻塞,t1,t2,t3每次執行會將cnt-1,然后繼續執行。直到cnt的值為0,則TA繼續執行。
假設只有兩個車道,同一地點,只能同時有兩輛車通過,即並發就是兩個。Semaphore優勢是可以控制同一時間,線程的並發量。
原子性介紹:
先看看jdk中atomic包中的原子類:
看下圖程序,拿atomicInteger
當調用count的incrementAndGet方法時候,內部調用下圖所示方法:
Var1指的是count對象,
底層是compareAndSwapInt,該方法是個本地方法,從名字看出就是CAS操作。含義是拿到var2主內存的值和傳入的var2值比較,如果相同,則執行相加操作。
atomicRefence的用法:
下圖最后結果是4
AtomicIntegerFieldUpdater用法:
atomicBoolean里的cas,只能執行一次。含義是多個線程同時執行,只有一個線程執行該操作,其他線程不能執行。
比如下面代碼結果一定是true,因為雖然有5000個線程同時運行,只有一個線程修改AtomicBoolean屬性的變量
ABA問題:是指在某個線程CAS操作的時候,其他線程將A改成了B又改回了A,此時CAS發現A和底層的值A沒有變。為了解決這個問題,
注:1.如果子類繼承了父類,子類調用父類中synchronized方法,是沒有同步效果的(synchronized不屬於方法聲明);、
2. synchronized,修飾非靜態方法或者代碼塊時候,鎖定的是調用的對象。一個類的兩個不同對象調用該類的非靜態同步方法,由於鎖對象不同,是每個對象本身,所以是不起同步作用的。
如果修飾類或者靜態方法或者靜態代碼塊,鎖定的就是這個類,此時,一個類的不同實例。兩者很有區別。
原子對比:
下面介紹可見性:
Volatile可見性實現的方式(注意:volatile沒有原子性)
實現原理概括就是,讀取一個變量的時候,會強迫從主內存中讀取該變量,而寫一個變量的時候會強迫從線程工作空間刷新到主內存。具體如下:
關於有序性:
指令重排序不會影響單線程,但是會影響多線程
JVM的happend-before原則:
如果兩個操作的執行,不能從happens-before原則中推導出來,那么就不能保證他們的有序性,虛擬機可以隨意的對他們進行重排序。