AQS是阻塞式锁和相关同步器框架。
特点:
- 使用state来表示资源状态,子类维护状态,通过状态控制是否获取到锁
- getState - 获取 state 状态
- setState - 设置 state 状态
- compareAndSetState - cas 机制设置 state 状态
- state分独占模式和共享模式,独占模式只有一个线程可以访问资源
- 提供了基于FIFO的等待队列类似EntryList
- 提供了条件变量来实现等待通知,类似WaitSet
子类主要实现这样一些方法(默认抛出 UnsupportedOperationException)
tryAcquire
tryRelease
tryAcquireShared
tryReleaseShared
isHeldExclusively
CLH队列
AQS内部通过CLH队列来维护线程状态,是一个FIFO双向队列,入队时通过CAS+volatile的方式添加元素。
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
出队(解锁):将head指向node,p的next置位null。解锁不需要CAS。因为当前线程本身还持有锁呢,不会存在竞争。
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
state设计
state 使用 volatile 配合 cas 保证其修改时的原子性
使用32位int表示state状态
阻塞恢复设计
使用park&unpark来实现阻塞恢复
使用AQS自定义不可重入锁
package com.demo.lock;
import javafx.beans.binding.When;
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 MyLock implements Lock {
MySync mySync = new MySync();
@Override//失败进入阻塞队列
public void lock() {
mySync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
mySync.acquireInterruptibly(1);
}
@Override//只尝试一次,失败放弃
public boolean tryLock() {
return mySync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return mySync.tryAcquireNanos(1, unit.toNanos(time));
}
@Override
public void unlock() {
mySync.release(1);
}
@Override
public Condition newCondition() {
return mySync.newCondition();
}
class MySync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if (arg == 1) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
if (arg == 1) {
if (getState() == 0) {
throw new IllegalMonitorStateException();
}
compareAndSetState(1, 0);
setExclusiveOwnerThread(null);
return true;
}
return false;
}
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
protected Condition newCondition() {
return new ConditionObject();
}
}
}