• 查看 ReentrantLock 实现 源码 的理解记录!


    ReentrantLock lock = new ReentrantLock(); 
    
    lock.lock();
    
    lock.unlock();
    
    //ReentrantLock 源码中的使用
        class X {
    //实例化 ReentrantLock时,
    //如果添加boolean参数,
    //true是公平模式,
    //flase是非公平模式,
    //默认非公平,非公平模式下新来的线程并不一定就能先拿到锁,后来的也并不一定是后拿到锁
             ReentrantLock lock = new ReentrantLock();
            public void m() {
              lock.lock();
              try {
                // ... method body
              } finally {
                lock.unlock();
              }
            }
         }
    
    //公平模式   下的lock,直接进行 acquire操作
            final void lock() {
                acquire(1);
            }  
    // 非公平模式  下的lock,
    //会先 根据 compareAndSetState 方法返回的结果,
    //去尝试把当前线程设置成为  独占所有者线程,
    //如果不成功再进行  acquire操作。
            final void lock() {
    //compareAndSetState 根据cas 设置,
    //如果当前状态值等于期望值,
    //则将同步状态设置为给定的更新值。
    //compareAndSetState(0, 1)) 预期值为0,修改值为1,
    //如果现在的state值为0,就把state值设置为1,
    //把当前线程设置独占所有。
                if (compareAndSetState(0, 1))
    //把当前线程设置为  独占所有者线程
                    setExclusiveOwnerThread(Thread.currentThread());
                else
                    acquire(1);
            }
    
     
    
    //采用独占模式,忽略中断。
    //处理没有获取到锁的线程
    //tryAcquire:重新 获取 一次锁和进行锁重入的处理。
    //addWaiter:将线程添加到 同步 队列中。
    //acquireQueued:自旋 获取 锁。     
    //selfInterrupt:中断线程。
    //三个条件的 为and,如果 acquireQueued方法 返回true,selfInterrupt会中断线程
    public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt();//中断线程 } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } //执行不公平的tryLock。 //tryAcquire是在子类中实现的,但都需要不公平的尝试trylock方法。 final boolean nonfairTryAcquire(int acquires) { //获取当前线程 final Thread current = Thread.currentThread(); //获取state的值 int c = getState(); //如果state的值为空,说明没有人使用锁 //如果预期值 为0,设置state为 设置值 if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } //如果state的值不是0,判断 独占所有者线程 是否为自己, //如果 独占所有者线程 是自己,state的值加上 要修改的值 else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }   static final class Node { //指示节点在共享模式中等待的标记.   static final Node SHARED = new Node(); //指示节点在独占模式中等待的标记.   static final Node EXCLUSIVE = null; //同步队列中等待的线程等待超时或者被中断, //需要从同步队列中取消等待,节点进入该状态将不会变化   static final int CANCELLED = 1; //后继 结点的线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消, //将会通知后继节点,使后继节点的线程得以运行   static final int SIGNAL = -1; //节点在等待队列中,节点线程等待在Condition上, //当其他线程对Condition调用了Signal()方法后, //该节点将会从等待队列转移到同步队列中,加入到对同步状态的获取中 static final int CONDITION = -2; //表示下一次共享式同步状态获取将会无条件地被传播下去   static final int PROPAGATE = -3; //线程的等待状态volatile int waitStatus;   volatile int waitStatus;   } // 为当前线程和给定的模式创建节点 private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); Node pred = tail; if (pred != null) { //如果 尾节点 不为null //设置当前新创建节点的 前驱 节点为 尾节点 node.prev = pred; //判断当前状态值是否等于预期的尾节点pred //如果 预期值 尾节点 等于就将当前同步状态值更新尾节点为node if (compareAndSetTail(pred, node)) { //尾节点的后继结点为 新创建的节点 pred.next = node; return node; } } enq(node); return node; } private Node enq(final Node node) { for (;;) { //获取尾节点 Node t = tail; if (t == null) { //初始化同步队列 // 创建新的节点new node()作为头节点 //把 头节点 作为尾节点 //而此时队列的尾节点和头结点是同一个节点 //由于enq是一个死循环,会再次进入判断 尾节点是否为空, //已经设置 头节点和尾节点,进入else语句 if (compareAndSetHead(new Node())) tail = head; } else { //尾节点不为空,把传入的node的 前驱 节点设置为尾节点 node.prev = t; if (compareAndSetTail(t, node)) { //判断node节点是否是预期的尾节点t,如果是就更新尾节点t为node, //把 t 的后继节点设置为 传入的节点,此时的 尾节点为 传入的node t.next = node; return t; } } } } //以死循环的方式不停的获取同步状态
    //如果获取不到则阻塞节点中的线程, //而被阻塞线程只能依靠其前驱节点的出队列操作或者阻塞线程中断 final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { //获取 node节点的 前驱节点 final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { //如果传入node节点的前驱节点为head,并且 //当前 线程还能够获得到 锁,就把传入node节点,设置为head setHead(node); p.next = null; // help GC failed = false; return interrupted; } // shouldParkAfterFailedAcquire检查并更新未能获取的节点的状态 //parkAndCheckInterrupt 阻塞当前线程,暂停线程的轮询。
    //当Unlock时会做后续节点的Unpark唤醒线程继续争抢锁。
         if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed)//取消正在进行的获取尝试 cancelAcquire(node); } } //检查并更新未能获取的节点的状态,
    //首先检查一下当前Node的前置节点pred是否是SIGNAL
    //如果是SIGNAL,那么证明前置Node的线程已经Park了,
    //如果waitStatus>0,那么当前节点已经Concel或者中断。
    //那么不断调整当前节点的前置节点,将已经Concel的和已经中断的线程移除队列。
    //如果waitStatus<0,那么设置waitStatus为SIGNAL,
    //因为调用shouldParkAfterFailedAcquire的方法为死循环调用,所以终将返回true。
    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus; if (ws == Node.SIGNAL) //如果线程阻塞,则返回true。 return true; if (ws > 0) { do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { //判断pred节点的waitStatus值,是否为预期的ws //如果是就更新 为 Node.SIGNAL,阻塞pred compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false; }


      
        lock.unlock();
        public void unlock() {
            sync.release(1);
        }
    
        public final boolean release(int arg) {
            if (tryRelease(arg)) {
                Node h = head;
                if (h != null && h.waitStatus != 0)
                    unparkSuccessor(h);
                return true;
            }
            return false;
        }
    
        private void unparkSuccessor(Node node) {
            int ws = node.waitStatus;
            if (ws < 0)
                compareAndSetWaitStatus(node, ws, 0);
            Node s = node.next;
            if (s == null || s.waitStatus > 0) {
                s = null;
                for (Node t = tail; t != null && t != node; t = t.prev)
                    if (t.waitStatus <= 0)
                        s = t;
            }
            if (s != null)
                LockSupport.unpark(s.thread);
        }
    
       protected final boolean tryRelease(int releases) {
             int c = getState() - releases;
             if (Thread.currentThread() != getExclusiveOwnerThread())
                 throw new IllegalMonitorStateException();
             boolean free = false;
             if (c == 0) {
                 free = true;
                 setExclusiveOwnerThread(null);
             }
             setState(c);
             return free;
        }
  • 相关阅读:
    Spring IoC和AOP使用扩展(二)
    Spring核心概念(一)
    MyBatis的动态SQL(五)
    MyBatis的SQL映射文件(四)
    初始myBatis(三)
    初始myBatis(二)
    微信小程序学习九 事件系统
    微信小程序学习八 wxs
    微信小程序学习七 视图层wxml语法
    微信小程序学习六 模块化
  • 原文地址:https://www.cnblogs.com/justincase/p/7918746.html
Copyright © 2020-2023  润新知