ReentrantLock解析

ReentrantLock lock = new ReentrantLock();//默認非公平鎖
lock.lock();//調用順序 NonfairSync.lock(),成功則設置線程獨佔,失敗則AbstractQueuedSynchronizer.acquire(1)[[[ 失敗就                                  //acquireQueued(addWaiter()),acquire這裏調用NonfairSync.tryAcquire(),tryAcquire中調用Syn.nonfairTryAcquire()]]]

lock.unlock();
            //AQS.release()然後調用Syn.tryRelease()
            //釋放成功則喚醒下一個節點

ReentrantLock fairlock=new ReentrantLock(true);
fairlock.lock();//調用順序 NonfairSync.lock(),直接調用AQS.acquire(1),acquire[[[中先調用FairSync.tryAcquire(1)  失敗就AQS.acquireQueued(addWaiter())  ]]]
    //tryAcquire中hasQueuedPredecessors()通過判斷"當前線程"是不是在CLH隊列的隊首,來返回AQS中是不是有比“當前線程”等待更久的線程,   有等待更久的就不獲取鎖

fairlock.unlock();

 

 

public class ReentrantLock implements Lock{
    private final Sync sync;//組合

    abstract static class Sync extends AbstractQueuedSynchronizer {
        abstract void lock();

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            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;
        }

        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;
        }

    }    

    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

    

public abstract class AbstractOwnableSynchronizer {
   private transient Thread exclusiveOwnerThread;  
   protected final void setExclusiveOwnerThread(Thread thread) {
        exclusiveOwnerThread = thread;
    }
   protected final void getExclusiveOwnerThread {
        return exclusiveOwnerThread;
    }//標記是否獨佔線程
}

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer{
    static final class Node {
         static final Node SHARED = new Node(); /** Marker to indicate a node is waiting in shared mode */

         static final Node EXCLUSIVE = null; /** Marker to indicate a node is waiting in exclusive mode */

         static final int CANCELLED =  1;   /**在同步隊列中等待的線程等待超時或被中斷,需要從同步隊列中取消該Node的結點即結束狀態,*進入該狀態後的結點將不會再變化*/
       static final int SIGNAL    = -1;  /**處於喚醒狀態,只要前繼結點釋放鎖,就會通知標識爲SIGNAL狀態的後繼結點的線程執行*/

  static final int CONDITION = -2; /** 該標識的結點處於等待隊列中,結點的線程等待在Condition上,當其他線程調用了Condition
                                         的signal()方法後,CONDITION狀態的結點將從等待隊列轉移到同步隊列中,等待獲取同步鎖*/

         static final int PROPAGATE = -3;// 與共享模式相關,在共享模式中,該狀態標識結點的線程處於可運行狀態
                                         //使用在共享模式頭結點有可能處於這種狀態,表示鎖的下一次獲取可以無條件傳播
         volatile int waitStatus;

         volatile Node prev;    volatile Node next;    volatile Thread thread;      Node nextWaiter;

         final Node predecessor(){};  //返回該節點的前一個節點

         Node() {    // Used to establish initial head or SHARED marker
        }

        Node(Thread thread, Node mode) {     // Used by addWaiter
            this.nextWaiter = mode;
            this.thread = thread;
        }
        Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }//Node類


    private transient volatile Node head;

    private transient volatile Node tail;

        private volatile int state;   //   0表示未鎖定   ,   1表示鎖定

    private Node enq(final Node node) { //入隊,第一個節點爲空節點,即head所指向的節點
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                       t.next = node;
                    return t;
                }
            }
           }
    }

    private Node addWaiter(Node mode) { //mode ShARED or EXCLUSIVE
        Node node = new Node(Thread.currentThread(), mode);
           Node pred = tail;
           if (pred != null) {//隊尾不爲空,則添加新節點到隊尾後面
            node.prev = pred;
                if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
                }
           }//嘗試一次快速入隊,入隊失敗則調用enque()循環入隊
        enq(node);
           return node;
    }
    private void setHead(Node node) {//拿到資源後,將head指向該結點。所以head所指的標杆結點,就是當前獲取到資源的那個結點或null。
        head = node;
        node.thread = null;
        node.prev = null;
    }
     //喚醒等待隊列中下一個線程
     private void unparkSuccessor(Node node) {//這裏,node一般爲當前線程所在的結點。
        int ws = node.waitStatus;
        if (ws < 0)//置零當前線程所在的結點狀態,允許失敗。
            compareAndSetWaitStatus(node, ws, 0);
        Node s = node.next; //找到下一個需要喚醒的結點s
        if (s == null || s.waitStatus > 0) {//如果爲空或已取消
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)//從這裏可以看出,<=0的結點,都是還有效的結點。
                    s = t;
        }
        if (s != null)//喚醒
            LockSupport.unpark(s.thread);
    } 

    private void cancelAcquire(Node node) {//取消正在進行的嘗試獲取
        if (node == null)// Ignore if node doesn't exist
            return;
        node.thread = null;  //1. node不再關聯到任何線程
        Node pred = node.prev;//2. 跳過被cancel的前繼node,找到一個有效的前繼節點pred
        while (pred.waitStatus > 0)
            node.prev = pred = pred.prev;
        Node predNext = pred.next;  
        node.waitStatus = Node.CANCELLED;//3. 將node的waitStatus置爲CANCELLED

        if (node == tail && compareAndSetTail(node, pred)) {//4. 如果node是tail,更新tail爲pred,並使pred.next指向null
            compareAndSetNext(pred, predNext, null);
        } 
        else      //5. 如果node既不是tail,又不是head的後繼節點 則將node的前繼節點的waitStatus置爲SIGNAL
            {     //並使node的前繼節點指向node的後繼節點(相當於將node從隊列中刪掉了)    
                int ws;        
                if (pred != head &&
                    ((ws = pred.waitStatus) == Node.SIGNAL || (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) 
                    && pred.thread != null) {
                    
                    Node next = node.next;
                    if (next != null && next.waitStatus <= 0)
                        compareAndSetNext(pred, predNext, next);
                } else {//6. 如果node是head的後繼節點,則直接喚醒node的後繼節點
                    unparkSuccessor(node);
                }

                node.next = node; // help GC
            }
    }

    final boolean acquireQueued(final Node node, int arg) {//把已經追加到隊列的線程節點(addWaiter方法返回值)進行阻塞,
            boolean failed = true;                        //但阻塞前又通過tryAccquire重試是否能獲得鎖,如果重試成功能則無需阻塞,直接返回
            try {
                boolean interrupted = false;
                for (;;) {
                    final Node p = node.predecessor();
                    if (p == head && tryAcquire(arg)) {
                        setHead(node);
                        p.next = null; // help GC
                        failed = false;
                        return interrupted;
                    }
                    if (shouldParkAfterFailedAcquire(p, node) &&
                        parkAndCheckInterrupt())
                        interrupted = true;
                }
            } finally {
                if (failed)
                    cancelAcquire(node);
            }
        }


   private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {/*配合使用acquireQueued()for無限循環設置*/
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)//首先檢查前趨結點的waitStatus位,如果爲SIGNAL,表示前趨結點會通知它,那麼它可以放心大膽地掛起了
            return true;
        if (ws > 0) {//是一個被取消的結點向前遍歷跳過被取消的結點,直到找到一個沒有被取消的結點爲止,
            do {     //將找到的這個結點作爲它的前趨結點,後進入acquireQueued的無限循環
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);  //如果前繼節點狀態爲非SIGNAL、非CANCELLED,則設置前繼
        }                                                    //的狀態爲SIGNAL,返回false後進入acquireQueued的無限循環
        return false;//返回false表示線程不應該被掛起。
    }

    private final boolean parkAndCheckInterrupt() {//park and then check if interrupted
        LockSupport.park(this);
        return Thread.interrupted();
    }

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //調用Sync中的tryAcquire()
            selfInterrupt();
    }


    public final boolean release(int arg) {
        if (tryRelease(arg)) {//調用Sync中的tryRealse()
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

    public final boolean hasQueuedPredecessors() {//通過判斷"當前線程"是不是在CLH隊列的隊首,來返回AQS中是不是有比“當                                                                               //前線程”等待更久的線程

        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
        return  h != t  && ((s = h.next) == null || s.thread != Thread.currentThread());
    }

 

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章