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