浅谈AQS
AQS是什么
- AbstractQuenedSynchronizer同步发生器,是用来构建Lock的,
- 基本思想:通过内置的FIFO队列来完成线程争夺资源的管理工作。
- 核心思想:CLH队列。如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
- 功能:子类定义为非公共内部帮助器类(私有的内部类继承AQS),写锁的时候一个帮助器,提供获取锁和释放锁的功能,可以看作是一种模板。
java.util.concurrent.locks的AbstractQueuedSynchronizer里面的方法。
acquire(int arg) ——以独占模式获取,忽略中断。
acquireShared(int arg)——以共享模式获取,忽略中断。
tryAcquireShared(int arg)——尝试以共享模式获取。
release(int arg) ——以独占模式释放锁对象
releaseShared(int arg)——以共享模式释放对象
acquire(int arg) ——以独占模式获取,忽略中断分析
// AbstractQueuedSynchronizer.class的方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
tryAcquire(arg)的方法(JavaAPI的说明):
addWaiter(Node.EXCLUSIVE), arg)的方法
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode); //以线程为节点
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
tryAcquire(arg)方法获取不到,则以线程作节点,在队列添加节点(addWaiter(Node.EXCLUSIVE), arg))
AQS的使用
/**
* @author 码提
* @Description 自定义锁
*/
public class MyLock implements Lock {
private Helper helper = new Helper();
public class Helper extends AbstractQueuedSynchronizer {
//获取锁
@Override
protected boolean tryAcquire(int arg) {
//获取状态值
int state = getState();
if (state == 0) {
//利用CAS原理修改state,保证原子性
if (compareAndSetState(0,arg)){
//设置当前线程占有资源
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
}else if (getExclusiveOwnerThread() == Thread.currentThread()) { //可重入锁
setState(getState() + arg);
return true;
}
return false;
}
//释放锁
@Override
protected boolean tryRelease(int arg) { //arg相当信号量,相当于减多少资源,当并不代表线程数量
int state = getState() - arg;
boolean flag = false;
if (state == 0) {
setExclusiveOwnerThread(null);
return true;
}
setState(state); //重入性问题
return false;
}
public Condition newCondition(){
return new ConditionObject();
}
}
@Override
public void lock() {
helper.acquire(1); //以独占方式获取锁
}
@Override
public void lockInterruptibly() throws InterruptedException {
helper.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return helper.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return helper.tryAcquireNanos(1,unit.toNanos(time));
}
@Override
public void unlock() {
helper.release(1);
}
@Override
public Condition newCondition() {
return helper.newCondition();
}
}
创作不易,转载请注明出处!