AQS CLH队列 Node节点浅析

AQS 实现的同步框架 构建和维护双向的同步队列
获取锁的方式 是独占还是共享? 能不能获取锁? 获取锁的优先级是公平还是非公平?都是有上层各种同步器实现实现的
这里说的锁都是aqs里面的一个volatile变量 aqs获取操作同步资源的接口 有实现类来定义逻辑

ReentrantLock 重写aqs获取和释放锁的方法 是否公平进入队列修改state同步资源 实现公平和非公平锁 锁作为一种标志 用来控制所有线程的并发行为
CountDownLatch 共享模式获取和释放锁 锁只是作为一种标志 用来唤醒因调用await方法阻塞再队列里面的线程

1:同步资源 即锁的实际表示
volatile int state;

state为0时表示没有线程持有 大于0时表示线程
对外方法
在这里插入图片描述
1 双向队列 遵循先进先出原则 (入队和出队时间复杂度都是O(1) 用空间换时间 )
是什么?
储存同步获取资源失败的线程 头结点持有锁 头结点释放锁之后会唤醒后面的节点

在这里插入图片描述
Node属性 sync nodes和condition nodes

        static final Node SHARED = new Node();//静态标识共享
        static final Node EXCLUSIVE = null;//静态标识独占

        static final int CANCELLED =  1;//当前节点是取消转态  加入队列后 尝试阻塞线程的过程中 线程获得了锁或者异常 则取消节点 
        static final int SIGNAL    = -1;//节点为SIGNAL  可以被前一个节点唤醒  
        static final int CONDITION = -2; //表示condition队列中  没有其他用处
        static final int PROPAGATE = -3; // 头结点拥有 确共享模式释放锁可持续进行下去  在共享模式释放锁的时候设置头结点
		//大于0 状态不可逆  可以直接判断节点的正负来判断节点是否可用  通过 cas修改
        volatile int waitStatus;

         //本节点检查状态依赖前一个节点  进队时候设置 出队的时候置空方便GC
         //如果前一个节点为cancel状态时 总能找到一个非cancel状态的节点 因为头结点不会是cancel状态
         //原因如下:队列在进入队列以后 尝试进入阻塞状态并在唤醒之后尝试获取锁
         //(acquireQueued|doAcquireInterruptibly|doAcquireNanos|doAcquireShared|doAcquireSharedInterruptibly|doAcquireSharedNanos)
         //这些都是节点入队以后的操作 他们的结构大致像下面这样  for循环有两个出口  一个unpark之后获取锁并取代头结点位置取代头结点位置 此时failed为false 不会进入cancelAcquire方法  头结点也就不会设置为cancel状态   
         //try {
         //   for (;;) {//两个出口 一个是获得锁 取代头结点位置  二线程抛异常 进入finally方法 }
         // } finally {
         //   if (failed)
     	 //     cancelAcquire(node);
         // }
        volatile Node prev;
        volatile Node next;
        volatile Thread thread;
        //1和内部类ConditionObject 的condition队列公用此节点类  ConditionObject 方便转移内部node节点到外部的fifo队列 
        //2 或者标识节点的等待状态时共享模式  (不会和condition冲突  condition都是独占模式)
        Node nextWaiter;
        final boolean isShared() {
            return nextWaiter == SHARED;
        }

       / /安全获取前节点 省去了判null 
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }

        Node() {
        }
   		// 入fifo队
        Node(Thread thread, Node mode) {  
            this.nextWaiter = mode;
            this.thread = thread;
        }

		//如condition队
        Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }

CLH变种队列
概念获取不到锁cas入队 关注前一个节点锁状态 然后一直自旋 (aqs 变种 关注前一个节点 但是会阻塞)
前一个节点释放锁只处理第一个节点 即第一个节点接受锁释放的事假 避免惊群现象 zookeeper使用类似的机制

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值