1. ReentrantLock可重入锁分为公平和非公平锁,通过构造函数进行设置,有时会用它来替代synchronized,区别在于前者能实现顺序公平,实现方式通过原子cas操作即cpu原语实现,而后者是通过字节码monitor-enter以及monitor-exit实现,
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
2. 获取锁,以及两种锁不同的实现,NonfairSync会先通过cas操作设置状态,失败后才会执行父类操作
public void lock() {
sync.lock();
}
// 非公平锁
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
// 公平锁
final void lock() {
acquire(1);
}
父类通过tryAcquire操作尝试获取锁,失败后会把该线程加入到等待队列中。
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
NonfairSync实现如下,先通过状态判断当前锁是否被强占,如果没的话就会通过cas操作抢占锁并且设置本线程为当前锁的持有线程,如果状态不为0即代表当前锁已经被强占,通过判断持有锁的线程是否为本线程来进行后续操作,如果为本线程的话就为状态加一,也是为了后续的每次释放减去相应的一,用来实现可重入。
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
FairSync的实现就是增加一个前置条件,当没有线程持有锁时判断锁的等待队列中是否有其他线程,以此来实现公平锁。
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
3. 可被中断的获取锁,会抛出InterruptedException异常。其他的和不可中断获取操作类似。
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
4. 尝试获取锁直接通过cas操作获取锁,或者判断当前持有锁的线程是否为本线程,快速响应。
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
5. 带有等待时间的尝试获取锁,成功则获取,失败则进入等待队列中直到限时停止。
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
6. 释放锁,判断持有锁的线程是否为本线程,不是则抛出异常,否则针对状态减去对应的数量一,重入锁的释放需要执行多次该操作,直到改状态为0才可以判断锁已经被本线程释放,删除锁的持有线程,才可以通过LockSupport.unpark操作通知其他线程获取锁,之前获取锁未成功的线程都被LockSupport.park所暂停。
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}