四.AQS的實現(xiàn)

一.ReentrantLock

  • 層次圖
    • ReentrantLock是獨占模式,其中NonfairSync 是非公平鎖,F(xiàn)airSync是公平鎖,構(gòu)造器就是構(gòu)造它們,Sync定義抽象Lock方法供子類實現(xiàn),unlock方法就是state減一。
public class ReentrantLock implements Lock, java.io.Serializable {
    public ReentrantLock() {  sync = new NonfairSync(); }
    public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
    private final Sync sync;
    abstract static class Sync extends AbstractQueuedSynchronizer { abstract void lock();}
    static final class NonfairSync extends Sync { }
    static final class FairSync extends Sync { }
   public void unlock() {sync.release(1);  }
}
  • 公平鎖的實現(xiàn)
    • 回想一下上節(jié)獲取鎖流程(Acquire):試圖獲取鎖(tryAcquire)若失敗,則進入acquireQueued方法獲取阻塞隊列
    • ReentrantLock獲取鎖方式:當(dāng)state=1,若當(dāng)前節(jié)點不是頭結(jié)點且是阻塞隊列第一個節(jié)點,并通過CAS將state值+1,阻止其他線程獲??;若state!=0且為當(dāng)前線程是獲取鎖的線程,則繼續(xù)講state+1;其他情況獲取鎖失敗
 static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;
        //AQS方法
        final void lock() {
            acquire(1);
        } 
       //AQS tryAcquire方法子類的實現(xiàn)
        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;
        }
    }
  • 非公平鎖的實現(xiàn)
    • 回想一下上節(jié)獲取鎖流程(Acquire):試圖獲取鎖(tryAcquire)若失敗,則進入acquireQueued方法獲取阻塞隊列
    • ReentrantLock獲取鎖方式:若state=0,當(dāng)前線程嘗試通過CAS看看能不能把state從0變?yōu)?(即獲取鎖),如果可以的話,直接獲取鎖而不需要排隊(按隊列順序)
 static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }
  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;
        }

二.信號量Semaphore實現(xiàn)原理

  • 信號量允許多條線程獲取鎖,它的鎖是一種共享鎖,信號量也有公平模式與非公平模式,與ReentrantLock類似
  • 實現(xiàn)方式
  • 通過設(shè)置permits(允許幾個線程)作為初始state,沒獲取一次state-1,,如果返回的是一個<0的數(shù)字,那么構(gòu)建FIFO隊列,線程阻塞,直到前面的執(zhí)行完才能喚醒后面的。
  FairSync(int permits) {
            super(permits);
        }

        protected int tryAcquireShared(int acquires) {
            for (;;) {
                if (hasQueuedPredecessors())
                    return -1;
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

三.CountDownLatch實現(xiàn)原理

  • 傳入一個count作為初始state,await的時候判斷是不是0,是0返回1表示成功,返回-1表示失敗,構(gòu)建FIFO隊列,head頭只連接一個Node,Node中的線程就是調(diào)用CountDownLatch的await()方法的線程,每次countDown的時候?qū)tate-1,直到state減到0的時候才算tryReleaseShared成功,tryReleaseShared成功,喚醒被掛起的線程
   private static final class Sync extends AbstractQueuedSynchronizer {
        Sync(int count) {
            setState(count);
        }

        int getCount() {
            return getState();
        }

        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

四.ThreadPoolExecutor的實現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容