AQS探究

juc其实就是包的缩写(java.util.concurrnt),通过下图展示了JUC里面有什么类。在这里插入图片描述AbstractQueuedSynchronizer(抽象队列同步器,简称AQS),就是J.U.C包的骨架,基于AQS,J.U.C包得以实现了的重入锁、读写锁、CountDownLatch(计数锁)、Semaphore(信号量)和FutureTask等类。

AQS中主要维护了state(锁状态的表示)和一个可阻塞的等待队列。
state是临界资源,也是锁的描述。表示有多少线程获取了锁。

private volatile int state;

关于state的get,set方法就不贴了,重要的是有个通过CAS修改state的方法。

//设置期望值,想修改的值。通过CAS操作实现。
protected final boolean compareAndSetState(int expect, int update) {
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

除此之外,还维护了等待队列(也叫CHL队列,同步队列)的头节点和尾节点。

private transient volatile Node head;

private transient volatile Node tail;

CHL队列由链表实现,以自旋的方式获取资源,是可阻塞的先进先出的双向队列。通过自旋和CAS操作保证节点插入和移除的原子性。当有线程获取锁失败,就被添加到队列末尾。下面我们来看看每个节点是怎么实现的。

二、内部类-Node
AQS的工作模式分为独占模式共享模式,记录在节点的信息中。它还使用了模板方法设计模式,定义一个操作中算法的骨架,而将一些步骤的实现延迟到子类中。比如获取资源的方法就能很好的品味模板模式。一般地,它的实现类只实现一种模式,ReentrantLock就实现了独占模式;但也有例外,ReentrantReadAndWriteLock实现了独占模式和共享模式。下面来看Node相关源码。

    //当前节点处于共享模式的标记
    static final Node SHARED = new Node();
   
    //当前节点处于独占模式的标记
    static final Node EXCLUSIVE = null;

    //线程被取消了
    static final int CANCELLED =  1;
    //释放资源后需唤醒后继节点
    static final int SIGNAL    = -1;
    //等待condition唤醒
    static final int CONDITION = -2;
    //工作于共享锁状态,需要向后传播,
    //比如根据资源是否剩余,唤醒后继节点
    static final int PROPAGATE = -3;

    //等待状态,有1,0,-1,-2,-3五个值。分别对应上面的值
    volatile int waitStatus;

    //前驱节点
    volatile Node prev;

    //后继节点
    volatile Node next;

    //等待锁的线程
    volatile Thread thread;

    //等待条件的下一个节点,ConditonObject中用到
    Node nextWaiter;

对于等待状态(waitStatus)做一个解释。

  • CANCELLED =1 线程被取消了
  • SIGNAL =-1 释放资源后需唤醒后继节点
  • CONDITION = -2 等待condition唤醒
  • PROPAGATE = -3 (共享锁)状态需要向后传播
  • 0 初始状态,正常状态

CANCELLED

作废状态,该节点的线程由于超时,中断等原因而处于作废状态。是不可逆的,一旦处于这个状态,说明应该将该节点移除了。

SIGNAL

待唤醒后继状态,当前节点的线程处于此状态,后继节点会被挂起,当前节点释放锁或取消之后必须唤醒它的后继节点。

CONDITION

等待状态,表明节点对应的线程因为不满足一个条件(Condition)而被阻塞。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值