AQS-ReentrantLock-Lock源码详解
2022-03-20 21:59:02   0  举报             
     
         
 AQS-reentrantLock源码详解
    作者其他创作
 大纲/内容
 返回node
  进行第二次循环
  waitStatus
  waitStatus=0
  T2
  for (;;) 自旋,直到所有线程都堵塞
  unparkSuccessor(h)
    0
  X
  public static ReentrantLock lock = new ReentrantLock(true);
  等于0
  判断state的状态
  AbstractQueuedSynchronizer.class
  创建独占性的Node
  ReentrantLock.class 的FairSyn内部类
  true
  加锁
  tail = null
  返回true
  thread = T2
  成功
  获得锁失败
  lock.lock()
  t节点的next指针指向node
  没有阻塞线程/返回false
  prev
  exclusiveOwnerThread=null
  tryRelease(arg)
  thread = T1
  全部线程进队开始线程堵塞
  线程堵塞在这里
  /**     * 可重入锁,怎么实现类似于synchronized的功能     */    public static ReentrantLock lock = new ReentrantLock(true);    static boolean flag = false;    public static void main(String[] args) {        for (int i=0;i<10;i++){            new Thread(()->{                lock.lock();                System.out.println(Thread.currentThread().getName()+\"get lock\
  为什么修改头部节点的waiteStatus的状态: 因为持有锁的线程T0在释放锁的时候,得判断head节点的waitestate是否!=0,!=0成立,会把waitstate的状态 -1 -> 0想要唤醒排队中的第一个线程T1,T1被唤醒接着走循环,去抢锁,抢锁可能失败【非公平场景下,此时可能有线程T3持有锁,T1可能会再次被阻塞,head节点需要再次循环判断,修改为-1
  h != null && h.waitStatus != 0头部节点不为空,且waitStatus!=0
  创建节点(null)Node
  解锁后会通知堵塞线程
   LockSupport.park(this);
  不为0
  false
  state+1;返回true
  解锁
  next
  !hasQueuedPredecessors()队列中没有排队
  获得公平锁/非公平锁
  T1
  thread = null
  获得ReentrantLock可重入锁
  head = null
   parkAndCheckInterrupt()阻塞线程
  node.predecessor()获得头部节点
  获得锁是否成功
  public ReentrantLock(boolean fair) {        sync = fair ? new FairSync() : new NonfairSync();    }
  ReentrantLock.class 的Syn内部类
  再一次尝试去获锁
  Thread.interrupted()返回判断线程是否有中断信号
  p == head && tryAcquire(arg)头部节点且可以加锁成功
  acquire(1);
  判断exclusiveOwnerThread是否为当前线程
  state = 0
  竞争锁失败,返回false
  thread = T1->null
  node.prev = t;把当前node节点的指针指向t
  LockSupport.unpark(s.thread)
  设置exclusiveOwnerThread为当前线程
  pred =null
  tryAcquire(arg)
  FairSync().lock()
  失败/阻塞线程
  结果true/false
  竞争锁/CAS
  t
  Node t = tail;t==null
  setHead(node); p.next = null;把head节点往后挪,新的头部节点就是当前节点
  lock.unlock();
  前驱节点.waitStatus==Node.SIGNAL
  修改state=0设置setExclusiveOwnerThread(null)
  flase循环
  p-t
  返回false
  调用
  代表此节点的状态/可被唤醒
  第一轮循环
  enq(node);入队
  修改头部节点waitStatus =0-1 -> 0
  for (;;) 自旋,直到所有线程入队
  AbstractQueuedSychronized
  等于-1
  addWaiter(Node.EXCLUSIVE)
  获得锁
  首先再尝试一次获得锁
  获得锁成功,true
   
 
 
 
 
  0 条评论
 下一页
  
   
   
   
   
  
  
  
  
  
  
  
  
 