国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[JDK源碼]J.U.C-AQS-ReentrantLock

不知名網友 / 2244人閱讀

摘要:公平鎖阻塞隊列前邊有線程,要去后邊排隊,簡單來說滾后邊等著去。非公平鎖不管是否有線程排隊,先槍鎖基于實現的可重入鎖實現類。

AQS原理介紹:

AQS (AbstractQueuedSynchronizer)底層一個隊列 阻塞隊列 ->
? Abstract:因為它并不知道怎么上鎖。模板方法設計模式即可,暴露出鎖邏輯。
? Queue :線程阻塞隊列 Synchronizer:同步
? CAS + state 完成多線程槍鎖邏輯 Queue 完成搶不到鎖的線程排隊

AQS核心代碼

//獲取鎖public final void acquire(int arg) {    if (!tryAcquire(arg) && // 子類判定獲取鎖是否失敗        acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) // 獲取失敗后添加到阻塞隊列        selfInterrupt();}// 子類實現獲取鎖的邏輯,AQS并不知道你怎么用這個state來上鎖protected boolean tryAcquire(int arg) {    throw new UnsupportedOperationException();}//釋放鎖的public final boolean release(int arg) {    // 子類判定釋放鎖成功    if (tryRelease(arg)) {        // 檢查阻塞隊列喚醒即可        Node h = head;        if (h != null && h.waitStatus != 0)            unparkSuccessor(h);        return true;    }    return false;}// 子類實現獲取鎖的邏輯protected boolean tryRelease(int arg) {    throw new UnsupportedOperationException();}

子類只需要實現自己的獲取鎖邏輯和釋放鎖邏輯即可,至于排隊阻塞等待、喚醒機制均由AQS來完成。

公平鎖:阻塞隊列前邊有線程,要去后邊排隊,簡單來說 滾后邊等著去。(FIFO) 非公平鎖:不管是否有線程排隊,先槍鎖

ReentrantLock

基于AQS實現的可重入鎖實現類。
ReentrantLock 是一個可重入的互斥(/獨占)鎖,又稱為“獨占鎖”
重入鎖: 自己可以再次獲取自己的內部的鎖。
state 來表示鎖狀態和重入次數,0無鎖,大于0 重入次數,1為重入1次,也即只加鎖一次

核心屬性

private final Sync sync;//sync,構造方法中初始化,決定使用公平鎖還是非公平鎖的方式獲取鎖。

構造方法

	public ReentrantLock() {        // 默認為非公平鎖。        sync = new NonfairSync();    }	public ReentrantLock(boolean fair) {        // 由fair變量來表明選擇鎖類型        sync = fair ? new FairSync() : new NonfairSync();    }

核心內部類

abstract static class Sync extends AbstractQueuedSynchronizer {}
static final class NonfairSync extends Sync {} 非公平鎖
static final class FairSync extends Sync {} 公平鎖

            //非公平鎖        static final class NonfairSync extends Sync {            // 由ReentrantLock調用獲取鎖            final void lock() {                // 非公平鎖,直接搶鎖,不管有沒有線程排隊                if (compareAndSetState(0, 1))                    // 上鎖成功,標識當前線程為獲取鎖的線程                    setExclusiveOwnerThread(Thread.currentThread());                else                    // 搶鎖失敗,進入AQS的標準獲取鎖流程                    acquire(1);            }            protected final boolean tryAcquire(int acquires) {                // 使用父類提供的獲取非公平鎖的方法來獲取鎖                return nonfairTryAcquire(acquires);            }        }        //公平鎖        static final class FairSync extends Sync {            // 由ReentrantLock調用            final void lock() {                // 沒有嘗試搶鎖,直接進入AQS標準獲取鎖流程                acquire(1);            }            // AQS調用,子類自己實現獲取鎖的流程            protected final boolean tryAcquire(int acquires) {                final Thread current = Thread.currentThread();                int c = getState();                // 此時有可能正好獲取鎖的線程釋放了鎖,也有可能本身就沒有線程獲取鎖                if (c == 0) {                   //這里和非公平鎖的區別在于:hasQueuedPredecessors看看隊列中是否有線程正在排隊,沒有的話再通過CAS搶鎖                    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;                }                //需要AQS來將當前線程放入阻塞隊列,然后進行阻塞操作等待喚醒獲取鎖                return false;            }        }        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()) {                    // 利用state 進行次數記錄                    int nextc = c + acquires;                    // 如果超過了int表示范圍,表明符號溢出,所以拋出異常                    if (nextc < 0)                        throw new Error("Maximum lock count exceeded");                    setState(nextc);//state 變量賦值                    return true;                }                //表明需要AQS來將當前線程放入阻塞隊列,然后進行阻塞操作等待喚醒獲取鎖                return false;            }            // 公平鎖和非公平鎖公用方法,在釋放鎖的時候,并不區分是否公平            protected final boolean tryRelease(int releases) {                int c = getState() - releases;                // 如果當前線程不是上鎖的那個線程                if (Thread.currentThread() != getExclusiveOwnerThread())                    throw new IllegalMonitorStateException();                boolean free = false;                // 不是重入鎖,那么當前線程一定是釋放鎖了,把當前AQS用于保存當前鎖對象的變量ExclusiveOwnerThread設置為null,表明釋放鎖成功                if (c == 0) {                    free = true;                    setExclusiveOwnerThread(null);                }                //此時state全局變量沒有改變,也就意味著在setState之前                //沒有別的線程能夠獲取鎖,保證了以上的操作原子性                setState(c);                //釋放鎖成功了,可以去喚醒正在等待鎖的線程                return free;            }            protected final boolean isHeldExclusively() {                return getExclusiveOwnerThread() == Thread.currentThread();            }            final ConditionObject newCondition() {                return new ConditionObject();            }        }

核心方法

public void lock() {//獲取鎖的操作    // 直接通過sync同步器上鎖    sync.lock();}public void unlock() {//釋放鎖的操作    sync.release(1);}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/125657.html

相關文章

  • java源碼

    摘要:集合源碼解析回歸基礎,集合源碼解析系列,持續更新和源碼分析與是兩個常用的操作字符串的類。這里我們從源碼看下不同狀態都是怎么處理的。 Java 集合深入理解:ArrayList 回歸基礎,Java 集合深入理解系列,持續更新~ JVM 源碼分析之 System.currentTimeMillis 及 nanoTime 原理詳解 JVM 源碼分析之 System.currentTimeMi...

    Freeman 評論0 收藏0
  • HashSet源碼分析:JDK源碼系列

    摘要:簡介繼續分析源碼,上一篇文章把的分析完畢。本文開始分析簡單的介紹一下。存儲的元素是無序的并且允許使用空的元素。 1.簡介 繼續分析源碼,上一篇文章把HashMap的分析完畢。本文開始分析HashSet簡單的介紹一下。 HashSet是一個無重復元素集合,內部使用HashMap實現,所以HashMap的特征耶繼承了下來。存儲的元素是無序的并且HashSet允許使用空的元素。 HashSe...

    用戶83 評論0 收藏0
  • HashMap 源碼詳細分析(JDK1.8)

    摘要:則使用了拉鏈式的散列算法,并在中引入了紅黑樹優化過長的鏈表。如果大家對紅黑樹感興趣,可以閱讀我的另一篇文章紅黑樹詳細分析。構造方法構造方法分析的構造方法不多,只有四個。 1.概述 本篇文章我們來聊聊大家日常開發中常用的一個集合類 - HashMap。HashMap 最早出現在 JDK 1.2中,底層基于散列算法實現。HashMap 允許 null 鍵和 null 值,在計算哈鍵的哈希值...

    monw3c 評論0 收藏0
  • 集合框架源碼學習之HashMap(JDK1.8)

    摘要:所謂拉鏈法就是將鏈表和數組相結合。若遇到哈希沖突,則將沖突的值加到鏈表中即可。在編寫程序中,要盡量避免。 目錄: 0-1. 簡介 0-2. 內部結構分析   0-2-1. JDK18之前   0-2-2. JDK18之后 0-3. LinkedList源碼分析   0-3-1. 構造方法   0-3-2. put方法   0-3-3. get方法   0-3-4. resize方法 ...

    yangrd 評論0 收藏0
  • JDK1.8源碼分析01之學習建議(可以延伸其他源碼學習)

    摘要:唐老師,回答道讀源碼是要建立在你的基礎經驗足夠的情況下。除了自己去閱讀源碼之外,比如學習某個類的時候,可以專門結合一些優質的博客針對性的對比學習,并查漏補缺。制定源碼學習計劃。多調試,跟蹤源碼。如若有好的學習方法,可以留言一起交流學習。 序言:目前看一看源碼,來提升自己的技術實力。同時現在好多面試官都喜歡問源碼,問你是否讀過JDK源碼等等? 針對如何閱讀源碼,也請教了我的老師。下面就先...

    ky0ncheng 評論0 收藏0

發表評論

0條評論

不知名網友

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<