1.AQS(AbstractQueuedSynchronizer )
AQS的必要性
是用來構(gòu)建鎖或者其他同步組件的基礎(chǔ)框架俗冻,它使用了一個int成員變量表示同步狀態(tài)礁叔,通過內(nèi)置的FIFO隊列來完成資源獲取線程的排隊工作。并發(fā)包的大師(Doug Lea)期望它能夠成為實現(xiàn)大部分同步需求的基礎(chǔ)迄薄。AQS使用方式和其中的設(shè)計模式
1.getState()
2.setState(int newState)
3.compareAndSetState(int expect,int update))-
模板方法設(shè)計模式
實現(xiàn)自定義同步組件時琅关,將會調(diào)用同步器提供的模板方法,
CLH隊列鎖
CLH隊列鎖也是一種基于鏈表的可擴(kuò)展讥蔽、高性能涣易、公平的自旋鎖,申請線程僅僅在本地變量上自旋冶伞,它不斷輪詢前驅(qū)的狀態(tài)新症,假設(shè)發(fā)現(xiàn)前驅(qū)釋放了鎖就結(jié)束自旋。ReentrantLock
ReentrantLock的構(gòu)造函數(shù)中碰缔,默認(rèn)的無參構(gòu)造函數(shù)將會把Sync對象創(chuàng)建為NonfairSync對象账劲,這是一個“非公平鎖”;
而另一個構(gòu)造函數(shù)ReentrantLock(boolean fair)傳入?yún)?shù)為true時將會把Sync對象創(chuàng)建為“公平鎖”FairSync金抡。鎖的可重入
重進(jìn)入是指任意線程在獲取到鎖之后能夠再次獲取該鎖而不會被鎖所阻塞瀑焦,該特性的實現(xiàn)需要解決以下兩個問題。
1)線程再次獲取鎖梗肝。鎖需要去識別獲取鎖的線程是否為當(dāng)前占據(jù)鎖的線程榛瓮,如果是,則再次成功獲取巫击。
2)鎖的最終釋放禀晓。線程重復(fù)n次獲取了鎖精续,隨后在第n次釋放該鎖后,其他線程能夠獲取到該鎖粹懒。鎖的最終釋放要求鎖對于獲取進(jìn)行計數(shù)自增重付,計數(shù)表示當(dāng)前鎖被重復(fù)獲取的次數(shù),而鎖被釋放時凫乖,計數(shù)自減确垫,當(dāng)計數(shù)等于0時表示鎖已經(jīng)成功釋放。
2.JMM基礎(chǔ)(Java Memory Model )
java線程的操作只能在自己的工作內(nèi)存中操作帽芽,不能直接操作主內(nèi)存
可見性
可見性是指當(dāng)多個線程訪問同一個變量時删掀,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值导街。原子性
即一個操作或者多個操作 要么全部執(zhí)行并且執(zhí)行的過程不會被任何因素打斷披泪,要么就都不執(zhí)行。volatile
volatile關(guān)鍵字修飾的變量會存在一個“l(fā)ock:”的前綴搬瑰。
該指令會將當(dāng)前處理器緩存行的數(shù)據(jù)直接寫會到系統(tǒng)內(nèi)存中款票,
且這個寫回內(nèi)存的操作會使在其他CPU里緩存了該地址的數(shù)據(jù)無效Synchronized
Synchronized在JVM里的實現(xiàn)都是基于進(jìn)入和退出Monitor對象來實現(xiàn)方法同步和代碼塊同步,雖然具體實現(xiàn)細(xì)節(jié)不一樣跌捆,但是都可以通過成對的MonitorEnter和MonitorExit指令來實現(xiàn)徽职。
對同步方法,從同步方法反編譯的結(jié)果來看佩厚,方法的同步并沒有通過指令monitorenter和monitorexit來實現(xiàn)姆钉,相對于普通方法,其常量池中多了ACC_SYNCHRONIZED標(biāo)示符抄瓦。
volatile 只保證了可見性
synchronized 可以保證可見性和原子性