ReentrantLock的實現原理及AQS和CAS

AQS,即AbstractQueuedSynchronizer, 隊列同步器,它是多線程訪問共享資源的同步器框架,Java中的ReentrantLock/Semaphore/CountDownLatch等同步組件都依賴於它。它維護了一個同步器狀態 (volatile int state 表明共享資源)和一個線程等待隊列(多線程爭用資源被阻塞時會進入此雙向隊列 ,FIFO )html

 

AQS大體流程,以ReentrantLock爲例多線程

       這篇講的比較清楚  http://www.javashuo.com/article/p-ytxwozhc-cr.html併發

     

      ReentrantLock 中的公平鎖和非公平鎖框架

      公平鎖能保證:老的線程排隊使用鎖,新線程仍然排隊使用鎖。 less

      非公平鎖保證:老的線程排隊使用鎖;可是可能會出現新線程要先於等待隊列中的線程搶佔到鎖ui

      公平鎖的實現是每次獲取鎖的時候會判斷等待隊列中是否還有線程在等待,而非公平鎖就不會判斷等待隊列中是否還有線程在等待,新來的線程有可能比等待中的線程先搶到鎖spa

      公平鎖獲取鎖的方法線程

 /**
         * 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) {
                // !hasQueuedPredecessors()保證了不管是新的線程仍是已經排隊的線程都順序使用鎖
                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;
        }

   非公平鎖獲取鎖的方法code

/**
         * Performs non-fair tryLock.  tryAcquire is implemented in
         * subclasses, but both need nonfair try for trylock method.
         */
        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;
        }

 

什麼是CASorm

在併發環境下,某個線程對共享變量先進行操做,若是沒有其餘線程爭用共享數據那操做就成功;若是存在數據的爭用衝突,那就纔去補償措施,好比不斷的重試機制,直到成功爲止,由於這種樂觀的併發策略不須要把線程掛起,效率要比採用鎖的機制高。在硬件指令集的發展驅動下,使得 "操做和衝突檢測" 這種看起來須要屢次操做的行爲只須要一條處理器指令即可以完成,這些指令中就包括很是著名的CAS指令(Compare-And-Swap比較並交換)

 

public final int incrementAndGet(){
        
        for(;;){
            int current=get();
            int next=current+1;
            if(compareAndSet(current,next)){

                return next;
            }    
        }
 }
相關文章
相關標籤/搜索