abstractQueueSync 作为juc 并发包下的核心,reentrantlock,smphere,CountDownLatch都是内部类Sync 实现了abstractQueueSync CyclicBarrier 也用到了它
reentrantlock 用的是排他锁
smphere,countdownlatch 用的是共享锁
CyclicBarrier用的是 reentrantlock +condition
所有实现类

Queue ? 队列?
找遍了 AbstractQueuedSynchronizer 里面没有发现真正的队列,只有一个内部类Node,这个Node里面有 前后指针 指向下一个node ,这其实是一个双向链表 。
同时有 Node head 标记为队列第一位置
java
AbstractQueuedSynchronizer{
private transient volatile Node head;
private transient volatile Node tail;
private volatile int state;
abstract static class Node {
volatile Node prev; // initially attached via casTail
volatile Node next; // visibly nonnull when signallable
Thread waiter; // visibly nonnull when enqueued
volatile int status; // written by owner, atomic bit ops by others
}
}
当我们 tryAcquire 如果失败的时候 会调用
AbstractQueuedSynchronizer # acquire(Node node, int arg, boolean shared,
boolean interruptible, boolean timed, long time)
去生成一个 Node
java
public final void acquire(int arg) {
if (!tryAcquire(arg))
acquire(null, arg, false, false, false, 0L);
}
java
final int acquire(Node node, int arg, boolean shared,
boolean interruptible, boolean timed, long time) {
Thread current = Thread.currentThread();
byte spins = 0, postSpins = 0; // retries upon unpark of first thread
boolean interrupted = false, first = false;
Node pred = null;
}
独占锁
规则:
- state ==0 才可以抢锁
- 抢到后ExclusiveOwnerThread 设置成当前线程
- 没抢到放到【队列里面】
reentrantlock 用的是独占锁
抢到锁的把 ExclusiveOwnerThread 设置成当前线程
并且设置 state = 1
公平锁
java
static final class FairSync extends Sync {
/**
* Acquires only if thread is first waiter or empty
*/
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && !hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
}
可以看到公平锁需要 在state = 0 的情况下 还要看下下一个是不是当前线程 ,
调用hasQueuedPredecessors() 查看下一个线程是不是自己
java
public final boolean hasQueuedPredecessors() {
Thread first = null; Node h, s;
if ((h = head) != null && ((s = h.next) == null ||
(first = s.waiter) == null ||
s.prev == null))
first = getFirstQueuedThread(); // retry via getFirstQueuedThread
return first != null && first != Thread.currentThread();
}
非公平锁
java
/**
* Acquire for non-reentrant cases after initialTryLock prescreen
*/
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
非公平锁只要判断state ==0 就可以抢锁了
ReentrantLock 的多重继承
ReentrantLock 设计很巧妙,用的是组合方式
java
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/** Synchronizer providing all implementation mechanics */
private final Sync sync;
/** Sync 才继承 AbstractQueuedSynchronizer **/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
}
/** 内部类 NonfairSync 又继承了 Sync 并且实现了 tryAcquire **/
static final class NonfairSync extends Sync {
protected final boolean tryAcquire(int acquires) {}
}
/** 内部类 FairSync 又继承了 Sync 并且实现了 tryAcquire **/
static final class FairSync extends Sync {
protected final boolean tryAcquire(int acquires) {}
}
}
NonfairSync 和 FairSync 只 实现了 tryAcquire 哈 ,因为释放逻辑不需要区分
tryRelease 是在 Sync
java
abstract static class Sync extends AbstractQueuedSynchronizer {
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (getExclusiveOwnerThread() != Thread.currentThread())
throw new IllegalMonitorStateException();
boolean free = (c == 0);
if (free)
setExclusiveOwnerThread(null);
setState(c);
return free;
}
}
ReentrantLock 使用 组合 + 内部类继承 AQS 的结构,
主要解决 Java 以下问题:
- Java 单继承限制
外部类不占用继承名额,扩展更灵活。 - 策略切换不灵活(公平 / 非公平)
用组合实现策略模式,运行时切换公平 / 非公平,避免类爆炸。 - API 暴露不安全、封装破坏
内部类隐藏 AQS 底层方法,对外只暴露安全 API。 - 代码复用(模板方法)
公共逻辑放父 Sync,差异逻辑放 Fair/Nonfair,减少重复代码。