实现思路
- 使用AQS(AbstractQueuedSynchronizer)框架:AQS是Java并发包中实现同步器的基础框架。通过继承AQS,并重写其几个关键方法来实现自定义锁。
- 可重入性:在获取锁时,记录当前持有锁的线程以及重入次数。当持有锁的线程再次获取锁时,增加重入次数而不是阻塞。
- 公平性:AQS内部维护一个FIFO队列来管理等待获取锁的线程。在获取锁时,判断当前队列是否有等待线程,如果有则按照队列顺序分配锁。
关键代码片段
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class CustomFairReentrantLock implements Lock {
// 自定义同步器
private static class Sync extends AbstractQueuedSynchronizer {
// 判断是否持有锁
protected boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
// 尝试获取锁
public 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()) {
setState(c + acquires);
return true;
}
return false;
}
// 尝试释放锁
protected 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;
}
// 获取条件变量
Condition newCondition() {
return new ConditionObject();
}
}
private final Sync sync = new Sync();
// 获取锁
@Override
public void lock() {
sync.acquire(1);
}
// 可中断地获取锁
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
// 尝试获取锁
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
// 在指定时间内尝试获取锁
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
// 释放锁
@Override
public void unlock() {
sync.release(1);
}
// 获取条件变量
@Override
public Condition newCondition() {
return sync.newCondition();
}
}