什么是AQS
AbstractQueuedSynchronizer(抽象队列同步器,简称AQS)出现在JDK 1.5中。AQS是很多同步器的基础框架,比如ReentrantLock、CountDownLatch和Semaphore等都是基于AQS实现的。除此之外,我们还可以基于AQS,定制出我们所需要的同步器。注意AQS是同步器是辅助我们更快捷的实现各种锁的框架, 并不是锁!!!
基于AQS实现自己的锁
由于AQS类中, 很多方法都是final的方法, 其实我们只需要重写部分方法就可以了. 可重写方法如下图, 而且这些方法AQS是要求使用者必须自己实现的, 否则会抛出UnsupportedOperationException
异常.
自定义实现同步器:
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
/**
* 同步器类
*/
public class MySynchronizer extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
// cas修改锁状态, compareAndSetState方法是AQS中的方法
if (super.compareAndSetState(0, 1)) {
// cas修改状态成功, 即加锁成功. 设置owner线程
super.setExclusiveOwnerThread(Thread.currentThread());
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
// state是volatile修饰的, 有写屏障, 所以放在setExclusiveOwnerThread方法后执行. 可以保证exclusiveOwnerThread的可见性
setState(0);
return true;
}
/**
* 是否持有独占锁
* @return
*/
@Override
protected boolean isHeldExclusively() {
return getState() > 0;
}
public Condition newCondition() {
return new ConditionObject();
}
}
自定义实现锁
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* 自定义不可重入锁
*/
public class MyLock implements Lock {
private MySynchronizer sync = new MySynchronizer();
/**
* 加锁, 加锁失败, 进入队列等待
*/
@Override
public void lock() {
sync.acquire(1);
}
/**
* 可打断的加锁
* @throws InterruptedException
*/
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
/**
* 尝试加锁, 加锁失败返回;不会等待
* @return
*/
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
/**
* 尝试加锁, 有等待时间
* @param time the maximum time to wait for the lock
* @param unit the time unit of the {@code time} argument
* @return
* @throws InterruptedException
*/
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
/**
* 解锁
*/
@Override
public void unlock() {
sync.release(1);
}
/**
* 创建条件变量
* @return
*/
@Override
public Condition newCondition() {
return sync.newCondition();
}
}