AQS你了解吗?
AQS是AbstractQueuedSynchronizer简称,这是一个抽象类,提供了被子类覆盖的protected方法。
在底层使用了CAS提供了乐观锁服务,如果冲突的时候,采用自旋方式进行重试,实现轻量级和高效的获取锁。
通过AQS实现一个简单的Lock:
在类中定义Sync内部类,
- Sync实现AbstractQueuedSynchronizer
- 重写:tryAcquire,tryRelease,isHeldExclusively
- 在tryAcquire中使用CAS,以预期值为0,写入更新值为1,如果更新成功则获取锁成功
- 最后提供lock,unLock两个方法
/**
* @author zhy
* @description 简单的AQS操作
* @date 2021/07/07 15:49
**/
public class SyncLock {
private final Sync sync;
public SyncLock() {
sync = new Sync();
}
public void lock() {
sync.acquire(1);
}
public void unlock() {
sync.release(1);
}
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
return compareAndSetState(0,1);
}
@Override
protected boolean tryRelease(int arg) {
setState(0);
return true;
}
// 该线程是否正在独占资源,只有用到Condition才需要去实现。
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
}
}
CAS是什么?
表象:CAS在Java中就是compareAndSet(expect,update),传入两个参数,一个是预期值,另外一个是更新值。如果被更新的变量预期值与传入值一致,就可以进行变更。
深层的调用是通过unsafe类的服务compareAndSwapInt(this,stateOffset,expect, update);
本质上:CAS是一种无锁算法,操作的是CPU指令操作,是原子操作,速度非常快。
优点:直接操作CPU指令集,速度快,而且避免了操作系统来裁定锁问题,开销比较小。