1.AQS
AQS是AbstractQueueSynchronization,抽象的队列同步器,它是实现同步器的基础组件,如常用的ReentrantLock、Semaphore、CountDownLatch等。
如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS的抽象表现。它将请求共享资源的线程封装成队列的结点(Node),通过CAS、自旋以及LockSupportpark()的方式,维护state变量的状态,使并发达到同步的控制效果。
状态
- getState():返回同步状态
- setState(int newState):设置同步状态
- compareAndSetState(int expect, int update):使用CAS设置同步状态
- isHeldExclusively():当前线程是否持有资源
独占资源(不响应线程中断)
- tryAcquire(int arg):独占式获取资源,子类实现
- acquire(int arg):独占式获取资源模板
- tryRelease(int arg):独占式释放资源,子类实现
- release(int arg):独占式释放资源模板
共享资源(不响应线程中断,读写锁的读锁)
- tryAcquireShared(int arg):共享式获取资源,返回值大于等于0则表示获取成功,否则获取失败,子类实现
- acquireShared(int arg):共享式获取资源模板
- tryReleaseShared(int arg):共享式释放资源,子类实现
- releaseShared(int arg):共享式释放资源模板
AQS的大概结构(如图,借用尚硅谷阳哥的图)
AQS的int变量
在AQS中维护了一个用关键字volatile修饰同步状态变量state ,代表着该共享资源的状态一更改就能被所有线程可见,而AQS的加锁方式本质上就是多个线程通过CAS完成对state值的修改,即volatile保证了可见性和有序性,用cas保证了原子性,当state为0时代表线程可以竞争锁,不为0时代表当前对象锁已经被占有。所以state的具体语义由实现者去定义,现有的ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch定义的state语义都不一样.
ReentrantLock
的state
用来表示是否有锁资源ReentrantReadWriteLock
的state
高16
位代表读锁状态,低16
位代表写锁状态Semaphore
的state
用来表示可用信号的个数CountDownLatch
的state
用来表示计数器的值
2.从ReentrantLock()
大概就是这个流程 一点点的跟。。。。。本人只是了解,不能清晰的解释仅供参考
public static void main(String[] args) {
//首先从你new了一个ReentrantLock锁开始
ReentrantLock reentrantLock = new ReentrantLock(true); //true表示是公平锁
reentrantLock.lock();
}
public ReentrantLock(boolean fair) {
//true则创建公平锁
sync = fair ? new FairSync() : new NonfairSync();
}
public ReentrantLock() {
//无参构造时创建的时非公平锁
sync = new NonfairSync();
}
// aqs是lock下面锁实现的底层基处,及ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch都会有个Sync类继承了AbstractQueuedSynchronizer类(也就是AQS)
abstract static class Sync extends AbstractQueuedSynchronizer{
abstract void lock();
/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
final boolean nonfairTryAcquire(int acquires) {
//获取当前的线程
final Thread current = Thread.currentThread();
//获取资源的状态如果是0可以抢占
int c = getState();
if (c == 0) {
//compareAndSetState(0, acquires)利用cas去尝试修改
if (compareAndSetState(0, acquires)) {
//抢到了进行把setExclusiveOwnerThread中的Thread指向当前线程
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;
}
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;
}
protected final boolean isHeldExclusively() {
//带有ExclusiveOwnerThread的方法都和AbstractOwnableSynchronizer有关
//AbstractOwnableSynchronizer有一个 private transient Thread exclusiveOwnerThread;
//exclusiveOwnerThread就是抢到资源那个把state变成1的线程 也就是抢到锁的线程
return getExclusiveOwnerThread() == Thread.currentThread();
}
//下面还有一些方法省略了
}
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
//抢到资源了
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
//AbstractQueuedSynchronizer类里面的
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
//中断标识
boolean interrupted = false;
//自旋
for (; ; ) {
//获取当前节点的前一个节点
final Node p = node.predecessor();
//如果这个节点是哨兵节点 则去抢占一下
// 先是调用NonfairSync的tryAcquire(实现了父类AQS的)
//然后最终调用Sync中的nonfairTryAcquire
if (p == head && tryAcquire(arg)) {
//抢占到了 把当前节点设置成头节点 把头节点(哨兵节点清除),
//把当前节点变成哨兵节点 最后原来的哨兵节点被gc回收
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//parkAndCheckInterrupt 方法利用LockSupport来把当前线程等待
//只有在持有锁释放的线程释放时进行unpark发令牌才能启动
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
//取消抢占
cancelAcquire(node);
}
}
private Node addWaiter(Node mode) {
//创建节点 因为clh队列是一个个节点组成
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
//因为一开始队列没有节点所以tail为null
Node pred = tail;
if (pred != null) {
//不会null把当前节点的前指针指向上一个尾节点
node.prev = pred;
//设置
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
private Node enq(final Node node) {
for (;;) {
Node t = tail;
//一开始会创建个哨兵节点并将头尾指针指向这个节点
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}