AQS(锁的基类)
基础描述
AbstractQueuedSynchronizer(AQS)这个抽象类,是Java并发包 java.util.concurrent 的基础工具类,是实现 ReentrantLock、CountDownLatch、Semaphore、FutureTask 等类的基础。
AbstractQueuedSynchronizer从名字上就可看出本质是一个线程锁的等待队列(Queue),其内部维护着FIFO的双向队列,也就是CLH队列。
AbstractQueuedSynchronizer其实是锁的主体。Lock类会有一个AQS类型的属性来实现锁。
AQS实现锁:
1,Lock类会有一个AQS类型的属性sync,sync是AQS的子类,
重写了tryAcquire()函数获取锁和tryRelease()函数释放锁。
2,当前线程获取到锁标志:
AQS.state > 0 && AQS.exclusiveOwnerThread == 当前线程。
AQS原理:
AQS中维护着一个同步队列:
1,头结点head是一个哨兵节点或者是已经获取到锁的线程,只有第二个节点能够尝试获取锁。
2,第二个节点获取到锁之后变为头结点。
AQS获取锁:
1,通过acquire函数调用tryAcquire获取锁,如果tryAcquire获取到锁结束流程。
2,如果没有竞争到锁,当前线程会封装成Node节点插入等待队列尾部。
AQS释放锁:
通过release调用tryRelease释放锁,当前线程释放锁后通过unparkSuccessor唤醒下一个等待队列中的线程.
AQS实现DEMO
//JDK给出的一个实现AQS的Demo示例(独占锁)。
class Mutex implements Lock, java.io.Serializable {
private static class Sync extends AbstractQueuedSynchronizer {
protected boolean isHeldExclusively() {
return getState() == 1;
}
public boolean tryAcquire(int acquires) {
assert acquires == 1;
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int releases) {
assert releases == 1;
if (getState() == 0)
throw new IllegalMonitorStateException();
setExclusiveOwnerThread(null);
setState(0);
return true;
}
Condition newCondition() {
return new ConditionObject();
}
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0);
}
}
private final Sync sync = new Sync();
public void lock() {
sync.acquire(1);
}
public boolean tryLock() {
return sync.tryAcquire(1);
}
public void unlock() {
sync.release(1);
}
public Condition newCondition() {
return sync.newCondition();
}
public boolean isLocked() {
return sync.isHeldExclusively();
}
public boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
}
1.AQS结构定义
//AQS结构定义
public abstract class AbstractQueuedSynchronizer ... {
//AQS等待队列的节点数据结构
static final class Node {
static final Node SHARED = new Node(); //共享锁模式
static final Node EXCLUSIVE = null; //独占锁模式
线程状态,小于等于0表示是正常状态,大于0表示线程排队被取消.
volatile int waitStatus;
volatile Node prev; /节点的前继节点,
volatile Node next; //节点的后继节点
volatile Thread thread; //节点对应的线程
Node nextWaiter; //锁的模式(共享锁或独占锁)
}
private transient volatile Node head; //队列头部节点
private transient volatile Node tail; //队列尾部节点
private volatile int state; //存储锁的数量
private transient Thread exclusiveOwnerThread; //当前持有锁的线程
}
- AQS.acquire函数
Lock.lock的入口:当前线程抢占锁资源,如果抢占成功函数返回true,否则不断尝试去抢占锁
//AQS(AbstractQueuedSynchronizer)抢占线程独占锁
public final void acquire(int arg) {
//调用AQS的acquire函数,此函数会执行如下几个流程:
//=>1,"tryAcquire"对当前线程进行加锁,如果加锁成功,直接结束流程,否则执行步骤2.
//=>2,"addWaiter"线程加锁失败,把线程添加到等待队列中(队列尾部),并执行步骤3.
//=>3,"acquireQueued"线程不断尝试抢占锁资源,如果抢占锁成功结束流程,否则执行步骤4.
//=>4,"selfInterrupt"表示线程处于BLOCKED状态,同时线程是标记为中断的线程
//===>1,同时被标记中断(读取中断标记后标记位会被清理),重新把线程标记为中断状态.
//===>2,在重新调用”selfInterrupt”会抛出”InterruptedException”异常(因为线程是BLOCKED状态),