AQS原理
全称是AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架
特点:
- 用state属性来表示资源的状态(分独占模式和共享模式),子类需定义如何维护这个状态,控制如何获取锁和释放锁
- getState - 获取state状态
- setState - 设置state状态
- compareAndSetState - 乐观锁机制设置state状态
- 独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源
- 提供了基于FIFO的等待队列,类似于Monitor的EntryList
- 条件变量来实现等待、唤醒机制,支持多个条件变量,类似于Monitor的WaitSet
子类主要实现这样一些方法(默认抛出UnsupportedOperationException)
- tryAcquire
- tryRelease
- tryAcquireShared
- tryReleaseShared
- isHeldExclusively
获取锁的姿势
// 如果获取锁失败
if(!tryAcquire(arg)){
// 入队,可以选择阻塞当前线程 park unpark
}
释放锁的姿势
// 如果释放锁成功
if(tryRelease(arg)){
// 让阻塞线程恢复运行
}
自定义锁(不可重入锁)
class MyLock implements Lock{
// 独占锁
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();
}
}
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 //创建条件变量
public Condition newCondition() {
return sync.newCondition();
}
}

浙公网安备 33010602011771号