AQS原理
概述
全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架
特点:
用 state 属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁
· getState - 获取 state 状态
· setState - 设置 state 状态
· compareAndSetState - cas 机制设置 state 状态
· 独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源
提供了基于 FIFO 的等待队列,类似于 Monitor 的 EntryList
条件变量来实现等待、唤醒机制,支持多个条件变量,类似于 Monitor 的 WaitSet
子类主要实现这样一些方法(默认抛出 UnsupportedOperationException)
· tryAcquire
· tryRelease
· tryAcquireShared
· tryReleaseShared
· isHeldExclusively
获取锁的写法
// 如果获取锁失败
if (!tryAcquire(arg)) {
// 入队, 可以选择阻塞当前线程 park unpark
}
释放锁的写法
// 如果释放锁成功
if (tryRelease(arg)) {
// 让阻塞线程恢复运行
}
实现不可重入锁
自定义同步器
// 独占锁
class MySync extends AbstractQueuedSynchronizer{
@Override// 尝试获取锁
protected boolean tryAcquire(int arg) {
if(compareAndSetState(0,1)){
// 加上锁了,并设置owner为当前线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override// 尝试释放锁
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override// 是否持有独占锁
protected boolean isHeldExclusively() {
return getState() == 1;
}
public Condition newCondition(){
return new ConditionObject();
}
}
自定义锁
有了自定义同步器,很容易复用 AQS ,实现一个功能完备的自定义锁
// 自定义锁(不可重入锁)
class MyLock implements Lock{
// 独占锁
class MySync extends AbstractQueuedSynchronizer{...}
private MySync sync = new MySync();
@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// 创建条件变量(类似synchronized 中的 wait set)
public Condition newCondition() {
return sync.newCondition();
}
}

被折叠的 条评论
为什么被折叠?



