1.AQS(AbstractQueuedSynchronizer )
AQS的必要性
是用來構建鎖或者其他同步組件的基礎框架,它使用了一個int成員變量表示同步狀態(tài),通過內(nèi)置的FIFO隊列來完成資源獲取線程的排隊工作。并發(fā)包的大師(Doug Lea)期望它能夠成為實現(xiàn)大部分同步需求的基礎。AQS使用方式和其中的設計模式
1.getState()
2.setState(int newState)
3.compareAndSetState(int expect,int update))-
模板方法設計模式
實現(xiàn)自定義同步組件時,將會調(diào)用同步器提供的模板方法,
image.gif CLH隊列鎖
CLH隊列鎖也是一種基于鏈表的可擴展、高性能、公平的自旋鎖,申請線程僅僅在本地變量上自旋,它不斷輪詢前驅的狀態(tài),假設發(fā)現(xiàn)前驅釋放了鎖就結束自旋。ReentrantLock
ReentrantLock的構造函數(shù)中,默認的無參構造函數(shù)將會把Sync對象創(chuàng)建為NonfairSync對象,這是一個“非公平鎖”;
而另一個構造函數(shù)ReentrantLock(boolean fair)傳入?yún)?shù)為true時將會把Sync對象創(chuàng)建為“公平鎖”FairSync。鎖的可重入
重進入是指任意線程在獲取到鎖之后能夠再次獲取該鎖而不會被鎖所阻塞,該特性的實現(xiàn)需要解決以下兩個問題。
1)線程再次獲取鎖。鎖需要去識別獲取鎖的線程是否為當前占據(jù)鎖的線程,如果是,則再次成功獲取。
2)鎖的最終釋放。線程重復n次獲取了鎖,隨后在第n次釋放該鎖后,其他線程能夠獲取到該鎖。鎖的最終釋放要求鎖對于獲取進行計數(shù)自增,計數(shù)表示當前鎖被重復獲取的次數(shù),而鎖被釋放時,計數(shù)自減,當計數(shù)等于0時表示鎖已經(jīng)成功釋放。
2.JMM基礎(Java Memory Model )



java線程的操作只能在自己的工作內(nèi)存中操作,不能直接操作主內(nèi)存
可見性
可見性是指當多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值。原子性
即一個操作或者多個操作 要么全部執(zhí)行并且執(zhí)行的過程不會被任何因素打斷,要么就都不執(zhí)行。volatile
volatile關鍵字修飾的變量會存在一個“l(fā)ock:”的前綴。
該指令會將當前處理器緩存行的數(shù)據(jù)直接寫會到系統(tǒng)內(nèi)存中,
且這個寫回內(nèi)存的操作會使在其他CPU里緩存了該地址的數(shù)據(jù)無效Synchronized
Synchronized在JVM里的實現(xiàn)都是基于進入和退出Monitor對象來實現(xiàn)方法同步和代碼塊同步,雖然具體實現(xiàn)細節(jié)不一樣,但是都可以通過成對的MonitorEnter和MonitorExit指令來實現(xiàn)。
對同步方法,從同步方法反編譯的結果來看,方法的同步并沒有通過指令monitorenter和monitorexit來實現(xiàn),相對于普通方法,其常量池中多了ACC_SYNCHRONIZED標示符。
volatile 只保證了可見性
synchronized 可以保證可見性和原子性
