公平鎖和非公平鎖1、什么是公平鎖?什么是非公平鎖?
2、兩者區(qū)別: 可重入鎖1、什么是可重入鎖?
method1是加了鎖的,method2也是加了鎖的,然后在method1里面調(diào)用method2。當(dāng)method1獲取了鎖之后,調(diào)用的method2雖然也是加了鎖的,但是不用重新獲取鎖了,這就叫可重入鎖。也就說,可以理解為method1和method2獲取到的鎖可以理解為同一把鎖。ReentrantLock和synchronized都是可重入鎖??芍厝腈i最大的作用就是防止死鎖。 2、可重入鎖demo:
看這段代碼,fun1一個(gè)同步方法,在里面輸出一句話,然后又調(diào)用了同步方法fun2。最后在main方法里面創(chuàng)建一個(gè)線程去執(zhí)行fun1方法。如果synchronized是可重入鎖,那么打印這兩個(gè)輸出語(yǔ)句的應(yīng)該是同一個(gè)線程。 ![]()
這段代碼只不過把synchronized換成了lock鎖,運(yùn)行結(jié)果是一樣的。以上兩端代碼說明synchronized和ReentrantLock都是可重入鎖。 自旋鎖前面聊CAS的時(shí)候說到了它底層用的就是UnSafe類和自旋鎖。這里就詳細(xì)說一說自旋鎖。
當(dāng)while條件不成立時(shí),就會(huì)一直執(zhí)行do語(yǔ)句,所以很消耗CPU。 舉個(gè)生活中的例子再來說明一下什么是自旋鎖:小明同學(xué)遇到了個(gè)問題,跑到講臺(tái)邊上去問老師。可是這時(shí)候老師在打電話,沒辦法立即給小明解答。小明就站在邊上干等著。這是小明就處于阻塞狀態(tài),做不了其他事。而自旋鎖就是,小明看到老師現(xiàn)在沒時(shí)間,就先回到座位上寫作業(yè),過一會(huì)兒再上去看,老師還沒時(shí)間,小明又回去做其他事。就這樣不斷的嘗試,知道成功。 2、手寫自旋鎖:
分析一下這段代碼:這個(gè)類有一個(gè)成員變量,原子引用類型的Thread,關(guān)于原子引用,之前在CAS詳解一文中說到過。這個(gè)類還有兩個(gè)方法,一個(gè)是myLock加鎖方法,一個(gè)是myUnlock,釋放鎖的方法。
用下面的代碼測(cè)試一下:
A線程進(jìn)去,發(fā)現(xiàn)當(dāng)前是thread是null,所以就將當(dāng)前線程指向自己。此時(shí)的當(dāng)前線程就是A,然后小睡5秒。在睡的過程中,B進(jìn)來了,發(fā)現(xiàn)當(dāng)前線程是A,所以進(jìn)入while循環(huán),一直進(jìn)行compareAndSet。5秒中后,A線程釋放鎖,將當(dāng)前線程設(shè)置為了null,這時(shí)B發(fā)現(xiàn)當(dāng)前線程是null了,就將當(dāng)前線程設(shè)置為了B,最后B也釋放鎖,將當(dāng)前線程設(shè)置為null。如果把線程A的myUnlock方法注釋掉,那么線程B將一直在while循環(huán)中出不來,造成死循環(huán)。 獨(dú)占鎖和共享鎖1、什么是獨(dú)占鎖?什么是共享鎖?
下面看一段代碼:
這段代碼就是模擬一個(gè)緩存,用HashMap存數(shù)據(jù)?,F(xiàn)在創(chuàng)建5個(gè)線程去寫,5個(gè)線程去讀,看看情況如何。
看運(yùn)行結(jié)果: ![]()
只需要在寫操作那里加寫鎖,在讀操作那里加讀鎖,這樣既可以保證數(shù)據(jù)的正確性,也提高了并發(fā)能力??催\(yùn)行結(jié)果: ![]()
![]() 說起鎖,好像有很多很多種,其實(shí)無外乎synchronized、ReentrantLock、ReentrantReadWriteLock和 自旋鎖。其他的都是從不同角度對(duì)這幾種鎖進(jìn)行分類而已。
|
|