并发——ReetrantLock —— 实现原理

1.ReetrantLock —— 实现原理:

实际组成:
获取到锁的:首先将status置为1,再一次获取这个锁的时候,在这个status上进行++的操作。
没有获取到锁的:有一个双向链表,进来的线程都挂在这个链表的尾部,保持头指针为null

加锁过程:
线程 1,2,3进来,可以选择公平锁和非公平锁的实现方式。

1)首先通过CAS去置位
        if 成功则占有锁
            标记自身占有锁,把state置为1
        else
            再去尝试 2)。
2)去获取一个state 
        if (state ==0)
            执行1)
        else if(state>0 && 占有的线程是当前线程)
            state++;
        else
            没有占有到锁
3) 将自己放入一个等待的FIFO的队列
        if(队列的尾节点==null)
            初始化,直接放入尾节点
        else(不为空){    
            将上一个节点的next指向该节点,使该节点成为新的尾节点
              if(当多个节点去占有尾节点){
                    whlie(每个线程放进队列里){
                          使用CAS去占有尾节点
                    }
              }         
        }
4 if(当前节点的头结点为Null){
              获取锁
              if(失败){
                     waitStatus == SIGNAL;
                     该线程挂起;
                      递归去挂起后面的等待节点的线程,都是将每个节点对应的waitStatus置为SIGNAL;
                  }
        }
注意:
AQS的FIFO的等待队列给解决在锁竞争方面的羊群效应问题提供了一个思路:保持一个FIFO队列,队列每个节点只关心其前一个节点的状态,线程唤醒也只唤醒队头等待线程。


参考:
https://blog.csdn.net/yanyan19880509/article/details/52345422
http://www.importnew.com/24006.html
https://blog.csdn.net/jiangjiajian2008/article/details/52226189

你可能感兴趣的:(并发——ReetrantLock —— 实现原理)