可見性?原子性??有序性 多線程三原則
volatile(不能修飾局部變量)
并發(fā)中存在可見性問題,volatile可以解決可見性問題,一個(gè)線程并不是不是永遠(yuǎn)看不到一個(gè)變量被修改,volatile能夠保證變量修改的及時(shí)性,不加volatile也能看到變量的修改,問題是不夠及時(shí),但是不能保證原子性
synchronized
JDK1.6之前 重量鎖 鎖的執(zhí)行涉及到系統(tǒng)底層 鎖的執(zhí)行效率低
JDK1.6之后 對鎖進(jìn)行了優(yōu)化,加入了膨脹升級機(jī)制,新增了偏向鎖,輕量級鎖,重量級鎖,鎖的強(qiáng)度只能升級不能降級,原因是:升級操作對性能是有影響的,既然在這個(gè)情況下鎖是隨時(shí)可能升級到重量級鎖的,那么就沒有必要降級
synchronize的四種種使用方式
1:直接修飾在類上
2:方法中的synchronize同步塊
3:synchronize修飾方法? 鎖誰new的這個(gè)對象就加在那個(gè)上面
4:synchronize修飾靜態(tài)方法 當(dāng)synchronize修飾靜態(tài)方法時(shí) 鎖是加在包含這個(gè)靜態(tài)方法的類.class上的
(性能考慮:不能在同一個(gè)類中寫很多的synchronize修飾的靜態(tài)方法,會導(dǎo)致代碼運(yùn)行質(zhì)量災(zāi)難性的下降)
synchronize屬于內(nèi)置鎖 對象鎖 互斥鎖 也是可以實(shí)現(xiàn)可重入的鎖
實(shí)現(xiàn)原理:一個(gè)線程獲取到鎖后,其他線程進(jìn)入while循環(huán)(自旋) 直到上一個(gè)線程執(zhí)行完畢(自旋過程中持續(xù)占用CPU資源,利用了CPU資源),釋放了鎖,這時(shí)候自旋中的線程競爭這把鎖,往下執(zhí)行
我們雖然無法知道拿到鎖的線程多久執(zhí)行完,但是我們可以獲取到正在自旋的線程的自旋次數(shù),根據(jù)這個(gè)次數(shù)來判斷競爭是否激烈,根據(jù)這個(gè)激烈程度的判斷進(jìn)行鎖的升級
鎖的重量級和有沒有鎖的標(biāo)識符存在堆中的對象區(qū)中的對象頭mark world 中
沒鎖存的對象的hashcode
偏向鎖有一個(gè)延遲啟動的過程 叫做匿名偏向鎖,即這個(gè)鎖還沒加,但是已經(jīng)準(zhǔn)備好加鎖這么一個(gè)過程
在對象頭中偏向鎖是存的線程iD
重量級鎖是存的指向互斥量的指針和輕量級鎖是存的棧中鎖記錄的指針