併發系列(十一)----- ReentrantLock的使用
一 簡介
ReentrantLock在中文的意思是重入鎖與synchronized同步語意一樣(具體的區別下面會總結),重入的意思是一個執行緒可以多次加鎖,但是釋放鎖的時候要釋放加鎖的次數。ReentrantLock實現就是利用AQS獨佔模式,內部維護了一個AQS的子類Sync,Sync有兩個子類FairSync和NofairSync這兩個分別是ReentrantLock的兩種鎖,公平鎖和非公平鎖(公平鎖與非公平鎖介紹)。因為ReentrantLock利用了AQS的獨佔模式,那麼ReentrantLock就可以使用等待佇列的相關功能。
二 ReentrantLock的簡單使用
如果只是簡單使用ReentrantLock,不使用同步佇列的話是比較簡單。使用方式如下
/** * ReentrantLock預設是非公平鎖 公平鎖的建立 private static final ReentrantLock lock = new ReentrantLock(true); */ private static final ReentrantLock lock = new ReentrantLock(); public void doSomeThing(){ lock.lock(); try { //執行業務邏輯,在這裡操作可保證執行緒安全 }finally { lock.unlock(); } }
使用方式是比較簡單,但是ReentrantLock提供加鎖的方式卻有不同的方式,具體說明如下
鎖定釋放只有一個方法unlock()。
三 ReentrantLock等待佇列的使用
在ReentrantLock中的Condition提供了Object中的wait(),和notify(),notifyAll()的功能,其中在Condition中的await開頭的方法與Object中的wait具有相同的功能,Condition中的signal()和signalAll()分別相當與Object中的notify()和notifyAll(),其中一個lock總可已有多個Condition
下面看程式碼
private static ReentrantLock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
final Thread hh = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println(Thread.currentThread() + "等待條件完成");
condition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread() + "終於等到條件完成了");
lock.unlock();
}
}
});
hh.start();
final Thread qq = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println(Thread.currentThread() + "條件完成了");
this.notifyAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
});
qq.start();
}
下面是等待相關的方法說明
喚醒的話是兩個方法signal()和singalAll()兩個方法,作用的話看方法名就知道了。一個是隻喚醒一個,一個是喚醒所有。
四 與synchronized的區別
ReentrantLock和synchronized具有相同的功能,在效能上不會有太大的差別,如果既可以用ReentrantLock也可以用synchronized的話,官方的建議是使用synchronized。因為synchronized在使用的時候比較方便的不用考慮釋放鎖,而ReentrantLock如果沒有釋放的話會是其它執行緒一直處於waiting狀態中。但是ReentrantLock也有它特有的功能
1. ReenTrantLock可以指定是公平鎖還是非公平鎖。而synchronized只能是非公平鎖。所謂的公平鎖就是先等待的執行緒先獲得鎖。
2. ReenTrantLock提供了一個Condition(條件)類,用來實現分組喚醒需要喚醒的執行緒們,而不是像synchronized要麼隨機喚醒一個執行緒要麼喚醒全部執行緒。
3. ReenTrantLock提供了一種能夠中斷等待鎖的執行緒的機制lock()方法
在同步的時候有上面3需要ReentrantLock的功能可以使用ReenTrantLock,在其他的情況下聽官方的。