ReentrantLock的实现依赖于java的同步器框架AbstractQueuedSynchronizer(AQS);
AQS使用一个整型的volatile变量(命名为state)来维护同步状态。
1、类图
2、example
public class ReentrantLockExample {
int a = 0;
ReentrantLock lock = new ReentrantLock(true);
public void writer() {
lock.lock(); //加锁
try {
a++;
} finally {
lock.unlock(); //解锁
}
}
public void reader() {
lock.lock(); //加锁
try {
int i = a;
} finally {
lock.unlock(); //解锁
}
}
}
3、公平锁
加锁
加锁方法lock()调用轨迹如下:
- ReentrantLock :lock()。
- FairSync :lock()。
- AbstractQueuedSynchronizer :acquire(int arg)。
ReentrantLock : tryAcquire(int acquires)。
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState(); //读volatile变量 state
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) { //cas更新
setExclusiveOwnerThread(current); //设置互斥锁拥有线程
return true;
}
}
else if (current == getExclusiveOwnerThread()) { //重入
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc); //写 volatile变量 sate
return true;
}
return false;
}
解锁
解锁方法unlock()调用轨迹如下:
ReentrantLock :unlock()。
- AbstractQueuedSynchronizer : release(int arg)。
- Sync : tryRelease(int release)。
protected final boolean tryRelease(int releases) {
int c = getState() - releases; //读volatile变量
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null); //设置互斥锁持有线程为null
}
setState(c); //写volatile变量
return free;
}
4、非公平锁
加锁
解锁