以前文章寫AQS的時候有說過公平鎖的代碼 這裏以非公平鎖來看一下java
面試的時候設計模式:模板方法 在AQS裏體現的淋漓盡致 ,你要是從設計模式扯到這裏,而後你正好又看過AQS在ReentrantLock中的實現,那你就能夠讓面試官眼前一亮面試
Lock lock = new ReentrantLock(false); lock.lock(); /** * 申請鎖 * * <p>Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * 若是沒有其餘線程持有這個鎖,就立刻返回,並設置鎖持有數爲1 * <p>If the current thread already holds the lock then the hold * count is incremented by one and the method returns immediately. * 若是當前線程持有鎖,就吧持有數量+1(可重入) 而後當即返回 * <p>If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired, * at which time the lock hold count is set to one. * 若是鎖被其餘線程持有,當前線程對於調度就不可用,而後睡着, 直到獲取鎖,而後把鎖持有數改成1 */ // ReentrantLock.class public void lock() { sync.lock(); } // NonfairSync.class final void lock() { // 先搶一下(上一篇說的 :小強二話不說先看看能不能跟老闆選餅) if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else // 若是沒有搶到 再去申請 acquire(1); } // AbstractQueuedSynchronizer.class public final void acquire(int arg) { // 這個tryAcquire會再搶一次(小強還抱着插隊的幻想) if (!tryAcquire(arg) && // 搶不到 就後邊排隊吧 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } // ReentrantLock.class protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } // ReentrantLock.class // 這裏須要瞭解AQS 我其餘文章有寫 能夠去看 final boolean nonfairTryAcquire(int acquires) { // 獲取當前線程 final Thread current = Thread.currentThread(); // 獲取state標誌位 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; }
有問題能夠留言哦,也能夠公衆號留言(回覆快):設計模式