• AQS


    转载自:https://www.jianshu.com/p/7b0e11a1e605

    J.U.C是基于AQS实现的,AQS是一个同步器,设计模式是模板模式。
    核心数据结构:双向链表 + state(锁状态)
    底层操作:CAS

       

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

    AQS中的int类型的state值,这里就是通过CAS(乐观锁)去修改state的值。lock的基本操作还是通过乐观锁来实现的。
    获取锁通过CAS,那么没有获取到锁,等待获取锁是如何实现的?我们可以看一下else分支的逻辑,acquire方法:

    1. tryAcquire:会尝试再次通过CAS获取一次锁。
    2. addWaiter:通过自旋CAS,将当前线程加入上面锁的双向链表(等待队列)中。
    3. acquireQueued:通过自旋,判断当前队列节点是否可以获取锁。

    可以看到,当当前线程到头部的时候,尝试CAS更新锁状态,如果更新成功表示该等待线程获取成功。从头部移除。
    基本可以确认,释放锁就是对AQS中的状态值State进行修改。同时更新下一个链表中的线程等待节点。

     

    可以看到在整个实现过程中,lock大量使用CAS+自旋。因此根据CAS特性,lock建议使用在低锁冲突的情况下。目前java1.6以后,官方对synchronized做了大量的锁优化(偏向锁、自旋、轻量级锁)。因此在非必要的情况下,建议使用synchronized做同步操作。

    AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。



  • 相关阅读:
    网络协议
    面向对象三大特性之多态
    面向对象三大特性之封装
    面向对象三大特性之继承
    python面向对象编程
    常用模块之configpaser与shutil
    XML模块
    Python模块之OS,subprocess
    Python日志(logging)模块,shelve,sys模块
    Linux 配置 Nginx
  • 原文地址:https://www.cnblogs.com/cq-Lucky/p/14427850.html
Copyright © 2020-2023  润新知