一篇文章,讓你明白重入鎖,自旋鎖,公平鎖及非公平鎖

sign = new AtomicReference<>(); public void lock() { Thread current = Thread.currentThread(); //null 不等於當前線程,返回false !fasle=true進入自選 while (!sign.compareAndSet(null, current)) { } } public void unlock() { Thread current = Thread.currentThread(); //對比current= 初始化信息,所以為true,並設置為null,此時// while (!sign.compareAndSet(null, current)),所以,null=null,lock中自旋結束,當一個鎖完成,sign中有回到初始化狀態。 sign.compareAndSet(current, null); }}

使用了CAS原子操作,lock函數將owner設置為當前線程,並且預測原來的值為空。unlock函數將owner設置為null,並且預測值為當前線程。

當有第二個線程調用lock操作時由於owner值不為空,導致循環一直被執行,直至第一個線程調用unlock函數將owner設置為null,第二個線程才能進入臨界區。

由於自旋鎖只是將當前線程不停地執行循環體,不進行線程狀態的改變,所以響應速度更快。但當線程數不停增加時,性能下降明顯,因為每個線程都需要執行,佔用CPU時間。如果線程競爭不激烈,並且保持鎖的時間段。適合使用自旋鎖。

一篇文章,讓你明白重入鎖,自旋鎖,公平鎖及非公平鎖

Lock常用API

MethodExplain
lock.getHoldCount()查詢當前線程報錯此鎖定的個數,也就是調用lock()的次數
lock.getQueueLength()返回正等待獲取此鎖定的線程估計數,比如有5個線程,1個線程首先執行await()方法,那麼在調用getQueueLength()方法後返回值是4,說明有4個線程同時在等待lock的釋放。
lock.getWaitQueueLength(condition)返回等待與此鎖定相關的給定條件Condition的線程估計數,比如有5個線程,每個線程都執行了同一個condition對象的await()方法,則調用getWaitQueueLength(Conditioncondition)方法時返回的int值是5。
lock.hasQueuedThread(thread)查詢指定的線程是否正在等待獲取此鎖定
lock.hasQueuedThreads()查詢是否有線程正在等待此鎖定
lock.hasWaiters(condition)是查詢是否有線程正在等待與此鎖定有關的condition條件
lock.isHeldByCurrentThread()查詢當前線程是否保持此鎖定
lock.isLocked()查詢此鎖定是否由任意線程保持
lock.lockInterruptibly()如果當前線程未被中斷,則獲取鎖定,如果已經被中斷則出現異常
lock.tryLock()僅在調用時鎖定未被另一個線程保持的情況下,才獲取該鎖定
lock.tryLock(long timeout, TimeUnit unit)方法booleantryLock(longtimeout,TimeUnitunit)的作用是,如果鎖定在給定等待時間內沒有被另一個線程保持,且當前線程未被中斷,則獲取該鎖定


分享到:


相關文章: