美文网首页
ReentrantLock公平锁和非公平锁(gold_axe)

ReentrantLock公平锁和非公平锁(gold_axe)

作者: 胖达_4b7e | 来源:发表于2020-10-26 00:13 被阅读0次

    里面有内部类 继承AQS



    AQS里面 提供状态, 几个队列

    加锁实际上是调 内部类Sync的lock


    区别是:

    非公平锁, 直接cas尝试拿锁2次
    公平锁首先看有没有线程在排队

    公平 | 非公平

    acquire() 是AQS里面提供

    tryAcquire是模板方法 子类各自实现, 非公平锁是 直接这再试一次, 公平锁是前面没了才试:

    公平 | 非公平
    可以看到, 就一句不同, 公平是前面没有排队了 才cas, 非公平不看前排队, 直接cas

    如果 tryAcquire失败acquireQueued 是AQS方法 对公平非公平都是一样的


    ↑ 这里会 互斥量 阻塞 park , 和syn重量锁一样
    会再试试, 前面是不是head, 是的话 就是刚好轮到我了 不用睡眠了

    就是说, 非公平锁 不管怎么样 来了先2次cas抢锁, 都失败才排队

    公平锁 为例

    1.第一次加锁 t1





    这里 head tail 都null , false马上返回, 啥都没做

    2.t1没结束, t2来拿锁了(如果t1已经结束, t2如t1)


    如果, tryAcquire失败, 就要入队了
    注意:
    就是说 , 如果 tryAcquire 没失败过, 从来就没冲突, t1 已经结束了, t2才来, 线程们是交替那锁的, AQS里面的双向链表根本不会初始化, 省了! t1 t2 是一样的流程!
    入队↓ 会初始化队列


    就是
    head字段指向head节点(图中的xx, 一个里面没线程的空节点),
    tail字段指向 t2产生的节点
    注意: addWaiter这里只是加入队列, 排队了 但是么有睡眠

    前面么有排队的 , 先 cas一次试试

    t1 没好, t2 睡眠排队中, t3来了

    前面和t2一样(除了不用队列已经初始化好了,这里只要插入节点 )

    这里是直接休眠了, 前面都有节点等着, 不用试了 , 直接park

    相关文章

      网友评论

          本文标题:ReentrantLock公平锁和非公平锁(gold_axe)

          本文链接:https://www.haomeiwen.com/subject/xxromktx.html