java~ReentrantLock的介紹
ReentrantLock
java除了使用關(guan)鍵字synchronized外(wai),還可以使用ReentrantLock實(shi)現獨占鎖的功(gong)能。而(er)且ReentrantLock相比synchronized而(er)言(yan)功(gong)能更加豐富,使用起來(lai)更為靈活,也更適合復雜的并發場景。這篇(pian)文章主要是從使用的角度來(lai)分析一下ReentrantLock。
ReentrantLock與synchronized來的區別
- synchronized是獨占鎖,加鎖和解鎖的過程自動進行,易于操作,但不夠靈活。ReentrantLock也是獨占鎖,加鎖和解鎖的過程需要手動進行,不易操作,但非常靈活。
- synchronized可重入,因為加鎖和解鎖自動進行,不必擔心最后是否釋放鎖;ReentrantLock也可重入,但加鎖和解鎖需要手動進行,且次數需一樣,否則其他線程無法獲得鎖。
- synchronized不可響應中斷,一個線程獲取不到鎖就一直等著;ReentrantLock可以相應中斷。
isFair()、isHeldByCurrentThread()和isLocked()
- lock.isFair()方法用來判斷lock鎖是公平鎖還是非公平鎖。公平鎖是指,線程獲得鎖的順序是按其等待鎖的先后順序來的,先來先獲得FIFO。反之,非公平鎖則是線程隨機獲得鎖的,lock默認是非公平鎖。
- lock.isHeldByCurrentThread()的作用是查詢當前線程是否保持此鎖定,和lock.hasQueueThread()不同的地方是:lock.hasQueueThread(Thread thread)的作用是判斷當前線程是否處于等待lock的狀態。
- lock.isLocked()的作用是查詢此鎖定是否由任意線程保持。
spring redis lock里有(you)(you)對(dui)ReentrantLock的使用,org.springframework.integration.redis.util.RedisLockRegistry,有(you)(you)興(xing)趣可以看一下它的源(yuan)碼。
用法示例
一 isFair()方法用來判斷lock鎖(suo)是(shi)公平鎖(suo)還(huan)是(shi)非公平鎖(suo)
public class ServiceIsFair {
public ReentrantLock lock;
public ServiceIsFair(Boolean isFair) {
this.lock = new ReentrantLock(isFair);
}
public void serviceMethod(){
try {
lock.lock();
System.out.println("公平鎖情況:"+lock.isFair());
} finally {
lock.unlock();
}
}
}
二 lock.isHeldByCurrentThread()的(de)作用是(shi)查詢當(dang)前線程是(shi)否保持此鎖定,與lock.hasQueueThread()不(bu)同的(de)地方(fang)是(shi):lock.hasQueueThread(Thread thread)的(de)作用是(shi)判斷當(dang)前線程是(shi)否處于等待lock的(de)狀態
public class ServiceIsHeldByCurrentThread {
private ReentrantLock lock;
public ServiceIsHeldByCurrentThread(Boolean isFair) {
this.lock = new ReentrantLock(isFair);
}
public void serviceMethod(){
try {
System.out.println("lock.isHeldByCurrentThread() "+lock.isHeldByCurrentThread());
lock.lock();
System.out.println("lock.isHeldByCurrentThread() "+lock.isHeldByCurrentThread());
} finally {
lock.unlock();
}
}
}
三 lock.isLocked()的作用是查詢(xun)此鎖定是否(fou)由任意線(xian)程(cheng)保(bao)持
public class ServiceIsLocked {
private ReentrantLock lock;
public ServiceIsLocked(Boolean isFair) {
this.lock = new ReentrantLock(isFair);
}
public void serviceMethod(){
try {
System.out.println("lock.isLocked() "+lock.isLocked());
lock.lock();
System.out.println("lock.isLocked() "+lock.isLocked());
} finally {
lock.unlock();
}
}
}