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();}
}