成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試突擊:公平鎖和非公平鎖有什么區別?

開發 后端
在 Java 語言中,鎖的默認實現都是非公平鎖,原因是非公平鎖的效率更高,使用 ReentrantLock 可以手動指定其為公平鎖。非公平鎖注重的是性能,而公平鎖注重的是鎖資源的平均分配,所以我們要選擇合適的場景來應用二者。

作者 | 磊哥

來源 | Java面試真題解析(ID:aimianshi666)

轉載請聯系授權(微信ID:GG_Stone)

從公平的角度來說,Java 中的鎖總共可分為兩類:公平鎖和非公平鎖。但公平鎖和非公平鎖有哪些區別?孰優孰劣呢?在 Java 中的應用場景又有哪些呢?接下來我們一起來看。

正文

公平鎖:每個線程獲取鎖的順序是按照線程訪問鎖的先后順序獲取的,最前面的線程總是最先獲取到鎖。非公平鎖:每個線程獲取鎖的順序是隨機的,并不會遵循先來先得的規則,所有線程會競爭獲取鎖。舉個例子,公平鎖就像開車經過收費站一樣,所有的車都會排隊等待通過,先來的車先通過,如下圖所示:

通過收費站的順序也是先來先到,分別是張三、李四、王五,這種情況就是公平鎖。而非公平鎖相當于,來了一個強行加塞的老司機,它不會準守排隊規則,來了之后就會試圖強行加塞,如果加塞成功就順利通過,當然也有可能加塞失敗,如果失敗就乖乖去后面排隊,這種情況就是非公平鎖。

應用場景

在 Java 語言中,鎖 synchronized 和 ReentrantLock 默認都是非公平鎖,當然我們在創建 ReentrantLock 時,可以手動指定其為公平鎖,但 synchronized 只能為非公平鎖。ReentrantLock 默認為非公平鎖可以在它的源碼實現中得到驗證,如下源碼所示:

當使用 new ReentrantLock(true) 時,可以創建公平鎖,如下源碼所示:

當使用 new ReentrantLock(true) 時,可以創建公平鎖,如下源碼所示:

公平和非公平鎖代碼演示

接下來我們使用 ReentrantLock 來演示一下公平鎖和非公平鎖的執行差異,首先定義一個公平鎖,開啟 3 個線程,每個線程執行兩次加鎖和釋放鎖并打印線程名的操作,如下代碼所示:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockFairTest {
static Lock lock = new ReentrantLock(true);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 3; i++) {
new Thread(() -> {
for (int j = 0; j < 2; j++) {
lock.lock();
System.out.println("當前線程:" + Thread.currentThread()
.getName());
lock.unlock();
}
}).start();
}
}
}

以上程序的執行結果如下圖所示:

接下來我們使用非公平鎖來執行上面的代碼,具體實現如下:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockFairTest {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 3; i++) {
new Thread(() -> {
for (int j = 0; j < 2; j++) {
lock.lock();
System.out.println("當前線程:" + Thread.currentThread()
.getName());
lock.unlock();
}
}).start();
}
}
}

以上程序的執行結果如下圖所示:

從上述結果可以看出,使用公平鎖線程獲取鎖的順序是:A -> B -> C -> A -> B -> C,也就是按順序獲取鎖。而非公平鎖,獲取鎖的順序是 A -> A -> B -> B -> C -> C,原因是所有線程都爭搶鎖時,因為當前執行線程處于活躍狀態,其他線程屬于等待狀態(還需要被喚醒),所以當前線程總是會先獲取到鎖,所以最終獲取鎖的順序是:A -> A -> B -> B -> C -> C。

執行流程分析

公平鎖執行流程

獲取鎖時,先將線程自己添加到等待隊列的隊尾并休眠,當某線程用完鎖之后,會去喚醒等待隊列中隊首的線程嘗試去獲取鎖,鎖的使用順序也就是隊列中的先后順序,在整個過程中,線程會從運行狀態切換到休眠狀態,再從休眠狀態恢復成運行狀態,但線程每次休眠和恢復都需要從用戶態轉換成內核態,而這個狀態的轉換是比較慢的,所以公平鎖的執行速度會比較慢。

非公平鎖執行流程

當線程獲取鎖時,會先通過 CAS 嘗試獲取鎖,如果獲取成功就直接擁有鎖,如果獲取鎖失敗才會進入等待隊列,等待下次嘗試獲取鎖。這樣做的好處是,獲取鎖不用遵循先到先得的規則,從而避免了線程休眠和恢復的操作,這樣就加速了程序的執行效率。公平鎖和非公平鎖的性能測試結果如下,以下測試數據來自于《Java并發編程實戰》:

從上述結果可以看出,使用非公平鎖的吞吐率(單位時間內成功獲取鎖的平均速率)要比公平鎖高很多。

優缺點分析

公平鎖的優點是按序平均分配鎖資源,不會出現線程餓死的情況,它的缺點是按序喚醒線程的開銷大,執行性能不高。非公平鎖的優點是執行效率高,誰先獲取到鎖,鎖就屬于誰,不會“按資排輩”以及順序喚醒,但缺點是資源分配隨機性強,可能會出現線程餓死的情況。

總結

在 Java 語言中,鎖的默認實現都是非公平鎖,原因是非公平鎖的效率更高,使用 ReentrantLock 可以手動指定其為公平鎖。非公平鎖注重的是性能,而公平鎖注重的是鎖資源的平均分配,所以我們要選擇合適的場景來應用二者。

責任編輯:姜華 來源: Java面試真題解析
相關推薦

2022-07-12 08:56:18

公平鎖非公平鎖Java

2022-12-26 00:00:04

公平鎖非公平鎖

2024-12-03 00:35:20

2023-10-07 08:17:40

公平鎖非公平鎖

2019-01-04 11:18:35

獨享鎖共享鎖非公平鎖

2023-03-26 21:51:42

2020-08-24 08:13:25

非公平鎖源碼

2018-07-31 15:05:51

Java公平鎖線程

2021-08-20 07:54:20

非公平鎖 Java多線編程

2022-08-22 07:06:32

MyBatisSQL占位符

2022-02-08 07:02:32

進程線程操作系統

2022-08-15 07:06:50

Propertiesyml配置

2022-08-03 07:04:56

GETHTTPPOST

2022-08-10 07:06:57

IoCDISpring

2022-04-24 07:59:53

synchronizJVMAPI

2021-06-02 21:31:39

Synchronous非公平模式

2021-07-02 08:51:09

Redisson分布式鎖公平鎖

2022-04-26 08:02:00

locktryLocklockInterr

2022-12-08 17:15:54

Java并發包

2021-06-30 14:56:12

Redisson分布式公平鎖
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 二区视频 | 成人av播放 | 成人免费视频观看视频 | 欧美炮房 | 欧美aaaaaaaa | 日韩在线电影 | 丁香久久 | 高清视频一区二区三区 | 亚洲欧美一区二区三区国产精品 | 九九综合| 自拍偷拍亚洲视频 | 无码国模国产在线观看 | 国产91在线 | 欧美 | 亚洲一区二区三区桃乃木香奈 | 精品国产乱码久久久久久丨区2区 | 国产色网 | 国产一级在线 | 偷拍第一页 | 国产成人精品久久 | 国产精品96久久久久久 | 永久av| 99国产精品久久久久 | 久久精品国产一区二区电影 | www.久久精品 | 欧美在线日韩 | 精品欧美一区二区精品久久 | 日韩一区二区视频 | 噜噜噜色网 | 瑞克和莫蒂第五季在线观看 | 亚洲一一在线 | 国产午夜影院 | 丝袜美腿一区二区三区 | 日韩一二区在线观看 | 亚洲免费在线 | 午夜影院在线观看视频 | 欧美日韩在线不卡 | 视频二区| 在线一区| 日韩在线欧美 | 国产国拍亚洲精品av | 91精品国产91久久久久久密臀 |