ReentrantLock 是一個可重入的互斥鎖,它可以用于保護共享資源的通路。ReentrantLock 提供了公平鎖和非公平鎖兩種機制。
公平鎖會嚴格按照線程請求鎖的時間順序來配置設定鎖。而非公平鎖會忽略這種順序,随機選擇一個線程來配置設定鎖。
公平鎖的主要優點是避免線程饑餓,每個線程擷取鎖的等待時間比較平均。而非公平鎖能在整體上獲得更高的吞吐量,因為它減少了線程上下文切換的次數。
預設情況下,ReentrantLock 是非公平的。下面通過示例代碼來說明公平鎖和非公平鎖的差別:
非公平鎖:
ReentrantLock lock = new ReentrantLock();
公平鎖:
ReentrantLock lock = new ReentrantLock(true);
代碼示例:
public class FairnessTest {
public static void main(String[] args) {
ReentrantLock fairLock = new ReentrantLock(true);
ReentrantLock unfairLock = new ReentrantLock();
MyThread thread1 = new MyThread(fairLock, "Thread-1");
MyThread thread2 = new MyThread(fairLock, "Thread-2");
MyThread thread3 = new MyThread(unfairLock, "Thread-3");
MyThread thread4 = new MyThread(unfairLock, "Thread-4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
class MyThread extends Thread {
private ReentrantLock lock;
public MyThread(ReentrantLock lock, String name) {
super(name);
this.lock = lock;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
lock.lock(); // acquire the lock
try {
System.out.println(Thread.currentThread().getName() +
" is holding the lock...");
} finally {
lock.unlock(); // release the lock
}
}
}
}
運作結果:
Thread-1 is holding the lock...
Thread-3 is holding the lock...
Thread-3 is holding the lock...
Thread-2 is holding the lock...
Thread-3 is holding the lock...
Thread-1 is holding the lock...
Thread-3 is holding the lock...
Thread-2 is holding the lock...
Thread-3 is holding the lock...
Thread-1 is holding the lock...
Thread-4 is holding the lock...
Thread-2 is holding the lock...
Thread-4 is holding the lock...
Thread-1 is holding the lock...
Thread-4 is holding the lock...
Thread-2 is holding the lock...
Thread-4 is holding the lock...
Thread-4 is holding the lock...
Thread-1 is holding the lock...
Thread-2 is holding the lock...
Process finished with exit code 0
我們可以看到,公平鎖(FairnessTest)按照線程請求的順序配置設定鎖,而非公平鎖(UnfairnessTest)随機選擇線程擷取鎖。是以,結論是:公平鎖可以避免線程饑餓,維持等待鎖的線程順序;而非公平鎖可以在整體上獲得更高的吞吐量。