juc并发工具二-AQS

目录

 

1 AQS概述

2 模板方法模式

2.1 独占方式获取资源

2.2 独占方式释放资源

2.3 共享方式获取资源

2.4 共享方式释放资源


1 AQS概述

AQS全称即AbstractQueuedSynchronizer,抽象队列同步器,提供了一套依赖队列实现的FIFO的同步器框架,ReentrantLock,Semaphore,CyclicBarrier,CountDownLatch都是基于AQS实现的
AQS内部维护了一个volatile的state变量和一个CLH队列,框架图如下
AQS队列模型

2 模板方法模式

AQS定义了一组模版方法供子类覆盖
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。
isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。

2.1 独占方式获取资源

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }


首先尝试获取资源,如果获取资源失败则将当前线程以独占的方式添加到执行队列尾部
acquireQueued方法基于CAS不断尝试获取资源,有兴趣的同学可以看看源码实现机制

2.2 独占方式释放资源

    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

如果释放资源成功并且队列中有正在等待的线程则通过unparkSuccessor方法唤醒其中一个waitStatus<0的线程
waitStatus有如下几个状态:

    // 表征等待线程已取消的
    static final int CANCELLED =  1;
    // 表征需要唤醒后续线程
    static final int SIGNAL    = -1;
    // 表征线程正在等待触发条件(condition)
    static final int CONDITION = -2;
    // 表征下一个acquireShared应无条件传播
    static final int PROPAGATE = -3;

2.3 共享方式获取资源

    public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }

    如果获取成功则直接返回。如果获取失败则进入等待队列,自旋的方式不断尝试获取资源
    tryAcquireShared方法返回结果说明:
        >0:获取资源成功,并且还有剩余资源
        =0:获取资源成功,但是已经没有剩余资源
        <=:获取资源失败

2.4 共享方式释放资源

    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

 如果尝试释放资源成功,则进行释放资源并且唤醒下一个线程,返回true,否则返回false
部分内容参考文章:https://www.jianshu.com/p/0f876ead2846

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章