更新時(shí)間:2022-08-16 07:39:26 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1146次
從字面上看,其實(shí)很簡(jiǎn)單。公平意味著每個(gè)人都排隊(duì)買票。不公平是指有人開了超級(jí)VIP,跳線。所以在多線程中,有公平鎖和不公平鎖。如何理解?
公平鎖:多個(gè)線程按照申請(qǐng)鎖的先后順序獲得鎖,所有線程都在隊(duì)列中排隊(duì),保證了隊(duì)列中的第一個(gè)先拿到鎖。
優(yōu)點(diǎn):所有線程都可以獲得資源,不會(huì)在隊(duì)列中餓死。
缺點(diǎn):吞吐量會(huì)下降很多,除了隊(duì)列中的第一個(gè)線程外,其他線程都會(huì)被阻塞,cpu喚醒阻塞線程的開銷會(huì)很大。
不公平鎖:多個(gè)線程不按照申請(qǐng)鎖的順序獲取鎖,而是直接嘗試同時(shí)獲取鎖(插入隊(duì)列中)。如果獲取失敗(插入失敗),則進(jìn)入隊(duì)列等待(如果排隊(duì)失敗),如果可以獲取(成功跳轉(zhuǎn)隊(duì)列),則直接獲取鎖。
優(yōu)點(diǎn):可以減少CPU喚醒線程的開銷,整體吞吐效率會(huì)更高,而且CPU不必喚醒所有線程,會(huì)減少被調(diào)用的線程數(shù)。
缺點(diǎn):可能會(huì)導(dǎo)致隊(duì)列中排隊(duì)的線程無法獲取鎖或獲取鎖時(shí)間過長(zhǎng),餓死。
在Java多線程并發(fā)操作中,我們操作鎖大部分時(shí)候都是基于Sync本身實(shí)現(xiàn)的,但是Sync本身是ReentrantLock本身的一個(gè)內(nèi)部類,而Sync本身繼
從字面上看,其實(shí)很簡(jiǎn)單。公平意味著每個(gè)人都排隊(duì)買票。不公平是指有人開了超級(jí)VIP,跳線。所以在多線程中,有公平鎖和不公平鎖。如何理解?
公平鎖:多個(gè)線程按照申請(qǐng)鎖的先后順序獲得鎖,所有線程都在隊(duì)列中排隊(duì),保證了隊(duì)列中的第一個(gè)先拿到鎖。
優(yōu)點(diǎn):所有線程都可以獲得資源,不會(huì)在隊(duì)列中餓死。
缺點(diǎn):吞吐量會(huì)下降很多,除了隊(duì)列中的第一個(gè)線程外,其他線程都會(huì)被阻塞,cpu喚醒阻塞線程的開銷會(huì)很大。
不公平鎖:多個(gè)線程不按照申請(qǐng)鎖的順序獲取鎖,而是直接嘗試同時(shí)獲取鎖(插入隊(duì)列中)。如果獲取失敗(插入失敗),則進(jìn)入隊(duì)列等待(如果排隊(duì)失敗),如果可以獲取(成功跳轉(zhuǎn)隊(duì)列),則直接獲取鎖。
優(yōu)點(diǎn):可以減少CPU喚醒線程的開銷,整體吞吐效率會(huì)更高,而且CPU不必喚醒所有線程,會(huì)減少被調(diào)用的線程數(shù)。
缺點(diǎn):可能會(huì)導(dǎo)致隊(duì)列中排隊(duì)的線程無法獲取鎖或獲取鎖時(shí)間過長(zhǎng),餓死。
在Java多線程并發(fā)操作中,我們操作鎖大部分時(shí)候都是基于Sync本身實(shí)現(xiàn)的,但是Sync本身是ReentrantLock本身的一個(gè)內(nèi)部類,而Sync本身繼承了AbstractQueuedSynchronizer,如圖:
那么我們?nèi)绾螌?shí)現(xiàn)公平鎖和不公平鎖呢?我們以買票為例,通過 ReentrantLock 進(jìn)行說明:
公共類 FairLocked 實(shí)現(xiàn) Runnable {
私人 int 座位號(hào) = 100;
/**
* 公平鎖實(shí)現(xiàn)ReentrantLock在構(gòu)造方法中設(shè)置為true:代表公平鎖
*
* 設(shè)置為false:表示不公平鎖默認(rèn)也是不公平鎖
*
*/
/** 私有 ReentrantLock 鎖 = new ReentrantLock(true); */
/** 私有 ReentrantLock 鎖 = new ReentrantLock(false); */
私有 ReentrantLock 鎖 = new ReentrantLock();
@Override
公共無效運(yùn)行(){
而(真){
嘗試 {
lock.lock();
如果(座位號(hào)> 0){
線程.sleep(100);
- 座位號(hào);
System.out.println(Thread.currentThread().getName() + "占用1個(gè)座位,還有一個(gè)座位" + seatNumber + "座位");
} 別的 {
System.out.println(Thread.currentThread().getName() + ": 不好意思,票賣完了!");
休息;
}
} 捕捉(InterruptedException e){
e.printStackTrace();
} 最后 {
lock.unlock();
}
}
}
公共靜態(tài)無效主要(字符串[]參數(shù)){
FairLocked rlbr = new FairLocked();
線程 t1 = new Thread(rlbr, "A window");
線程 t2 = new Thread(rlbr, "B window");
t1.start();
t2.start();
}
}
需要注意的是,默認(rèn)情況下是不公平的。如果你想要一個(gè)公平的鎖,你必須將它設(shè)置為 true。因此,查看上面的輸出,可以看到 A 線程和 B 線程之間存在資源爭(zhēng)用(跳線)。這是一個(gè)不公平的鎖。我們?cè)O(shè)置為true看看效果如何:
可以看出AB線程是非常有序的,也就是排隊(duì)執(zhí)行!如果大家想了解更多相關(guān)知識(shí),可以關(guān)注動(dòng)力節(jié)點(diǎn)的Java多線程編程,里面有更豐富的知識(shí)等著大家去學(xué)習(xí),希望對(duì)大家能夠有所幫助。
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743