簡述
ReentrantLock是java中非常重要的一個并發(fā)工具,相比于java原生的synchronized有著更好的性能
## 概念速查
ReentrantLock涉及的名稱和概念較多,這里做一個簡單的歸類和解釋,具體更為詳細(xì)的內(nèi)容,請自行Baidu或Google,這部分用于在閱讀文章的時候,快速了解一些名稱的概念,如果已經(jīng)熟悉,請?zhí)^。
快速預(yù)覽
更強大的功能,玩玩意味著更為復(fù)雜的使用,ReentrankLock的使用比起synchronize,多了一個主動釋放鎖的代碼,一個典型的使用示例如下
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// ... method body
}finally {
lock.unlock();
}
注意unlock的操作一定要置于finally塊中,這樣才能保證鎖一定能釋放。
uml圖
看完了簡單的使用示例,我們來快速的看一遍ReentrankLock的結(jié)構(gòu),下面是用idea的工具快速生成的uml圖,感謝idea,大大提高了我們的工作質(zhì)量。
ReentrantLock-UML
一次性過于深入的討論,往往會迷失在繁瑣的細(xì)節(jié)中,而難以把握全貌,而細(xì)節(jié)往往是由全局的目標(biāo)決定的,所以我們一層一層的談,不一次性深入最終代碼。
由uml圖,我們可以看出,ReentrantLock類是一個Lock接口的具體實現(xiàn),每個ReentrantLock的實例,都持有一個sync對象,且這個sync是final修飾的,這個sync有兩種具體的子類,分別是NonfairSync和FairSync,也就是非公平鎖和公平鎖。
ReentrantLock有兩個構(gòu)造方法,我們可以先看這兩個方法,
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = (fair)? new FairSync() : new NonfairSync();
}
可以看出,所謂構(gòu)造函數(shù),其實就是初始化需要使用的sync的類型,默認(rèn)是非公平鎖。參考公平鎖與非公平鎖
案例:并發(fā)賣火車票
public class Ticket implements Runnable {
// 當(dāng)前擁有的票數(shù)
private int num = 100;
ReentrantLock lock = new ReentrantLock();
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
lock.lock();
// 輸出賣票信息
if (num > 0) {
System.out.println(Thread.currentThread().getName() + ".....sale...." + num--);
}
lock.unlock();
}
}
}