ReentrantLock  FairSync的lock方法

ReentrantLock  FairSync的lock方法

if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();

1. tryAcquire(arg)  尝试去获取锁
    (1)aqs的state为0   hasQueuedPredecessors() 判断clh队列中是否有等待线程    没有  -cas将state改为1 成功后将当前线程设置为持有排它锁线程exclusiveOwnerThread
    (2) 如果是当前线程持有锁,则将state值+1 
     其他情况均为获取锁失败
2.  acquireQueued(addWaiter(Node.EXCLUSIVE), arg))  将当前线程放入clh队列中
  (1)addWaiter(Node.EXCLUSIVE) 将当前线程加入clh队列中
         <1>clh队列最后一节点有数据,则加入最后一个节点(将最后一个节点后驱指针指向当前节点,当前节点前驱指针指向最后一个节点)
         <2>clh队列最后一节点无数据,初始化clh队列并加入当前指针
(2) acquireQueued(addWaiter(Node.EXCLUSIVE), arg))  是否阻塞当前线程
       <1> 再用此节点进行一次尝试获取锁,条件是首先此节点是头节点,获取成功则完毕
        <2> 判断上一个节点的waitstate是否是1,也就是被中断过,有则循环判断,从clh对列中移除, 然后将waitstate改为-1.也就可以安全阻塞


ReentrantLock  FairSync的lock方法和NonfairSync的lock方法区别


                clh中有ABC三个线程阻塞中。   这个时候锁刚好空闲,D线程进来,非公平锁就会D线程去直接获取,有机会获取到。  公平锁的话,D不能获取,要到Clh对列中排队

UnLock方法

        就是将state值去减一直到为0,然后看头节点是否有值,有的话  LockSupport.unpark

//后续笔记是摘抄 图灵课堂杨过的笔记

Lock,公平与公平两种特性

三大核心原理

自旋,LocksSuport, CAS,queue队列

CAS依赖汇编指令:cmpxchg()

Lock可重入性:可重入!

synchronized:可重入

公平

```java
exclusiveOwnerThread 当前获取锁的线程是谁!
state 状态器

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

tryAcquire(arg) //锁竞争逻辑
//CLH 
addWaiter(Node.EXCLUSIVE) //线程入队,Node节点,Node对Thread引用
    Node:共享属性,独占属性 //响应式编程,异步非阻塞,FutureTask,Callbale
    创建节点Node = pre,next,waitestate,thread 重要属性
    waitestate节点的生命状态:信号量
        SIGNAL = -1 //可被唤醒
        CANCELLED = 1 //代表出现异常,中断引起的,需要废弃结束
        CONDITION = -2 // 条件等待
        PROPAGATE = -3 // 传播
        0 - 初始状态Init状态
为了保证所有阻塞线程对象能够被唤醒
compareAndSetTail(t, node) 入队也存在竞争
    
//当前节点,线程要开始阻塞
acquireQueued(Node(currentThread), arg)
    节点阻塞之前还得再尝试一次获取锁:
    1,能够获取到,节点出队,并且把head往后挪一个节点,新的头结点就是当前节点
    2、不能获取到,阻塞等待被唤醒
        1.首先第1轮循环、修改head的状态,修改成sinal=-1标记处可以被唤醒.
        2.第2轮循环,阻塞线程,并且需要判断线程是否是有中断信号唤醒的!
        shouldParkAfterFailedAcquire(p, node)
    waitestate = 0 - > -1 head节点为什么改到-1,因为持有锁的线程T0在释放锁的时候,得判断head节点的waitestate是否!=0,如果!=0成立,会再把waitstate = -1->0,要想唤醒排队的第一个线程T1,T1被唤醒再接着走循环,去抢锁,可能会再失败(在非公平锁场景下),此时可能有线程T3持有了锁!T1可能再次被阻塞,head的节点状态需要再一次经历两轮循环:waitState = 0 -> -1
   Park阻塞线程唤醒有两种方式:
    1、中断
    2、release()
```


               

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值