浅谈AQS

浅谈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的说明):
JAVA API的方法说明
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();
    }
}

创作不易,转载请注明出处!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值