国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

AQS源碼分析——以ReentrantLock為例

這篇具有很好參考價(jià)值的文章主要介紹了AQS源碼分析——以ReentrantLock為例。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

AQS自身屬性:

private transient volatile Node head;
private transient volatile Node tail;
private volatile int state;

Node屬性:

//	共享
static final Node SHARED = new Node();
//	獨(dú)占       
static final Node EXCLUSIVE = null;
// 線程被取消了        
static final int CANCELLED =  1;	
//	后繼線程需要喚醒      
static final int SIGNAL    = -1;
//	等待condition喚醒        
static final int CONDITION = -2;
//	共享式同步狀態(tài)獲取將會(huì)無(wú)條件地傳播下去       
static final int PROPAGATE = -3;
//	初始為0,狀態(tài)是上面的幾種
volatile int waitStatus;		//	很重要
//	前置節(jié)點(diǎn)
volatile Node prev;
//	后置節(jié)點(diǎn)
volatile Node next;

volatile Thread thread;
  1. 1. 以ReentrantLock為例,其他類舉一反三,方法lock()

  2. 2. Lock接口實(shí)現(xiàn)類,基本都是通過(guò)【聚合】了一個(gè) 【隊(duì)列同步器】的子類完成線程訪問控制的Sync實(shí)現(xiàn)lock;Sync繼承AQS;Sync又有兩個(gè)實(shí)現(xiàn)類。

  3. AQS源碼分析——以ReentrantLock為例

    
    //	公平與非公平鎖的構(gòu)造
    public ReentrantLock() {
           sync = new NonfairSync();
     }
     
    public ReentrantLock(boolean fair) {
           sync = fair ? new FairSync() : new NonfairSync();
    }
     

    ?公平鎖與非公平鎖的實(shí)現(xiàn):

  4. 1.0 
    //	非公平鎖
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;
    
        final void lock() {
            if (compareAndSetState(0, 1))	//	這里一開始省略了acquire,能搶到直接搶,搶不到再排隊(duì)
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
    
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);//	實(shí)現(xiàn)展開在下面
        }
    }
    
    1.1 
    //	非公平鎖的 tryAcquire實(shí)現(xiàn)細(xì)節(jié)
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {	//	這里判斷狀態(tài),1是被占用,0是不被占用。再嘗試搶一下,如果正好線程釋放鎖那么就正好搶到
            if (compareAndSetState(0, acquires)) { //	這里和公平鎖相比缺少了一個(gè)hasQueuedPredecessors()
                setExclusiveOwnerThread(current);		//	設(shè)置獲取排他鎖的線程
                return true;	//
            }
        } else if (current == getExclusiveOwnerThread()) { //	這里判斷是不是自己持有鎖,自己持有就進(jìn)去,畢竟可重入鎖
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;		//	即不空閑也不是自己占用鎖,則返回false
    }
    
    
    2.0
    //	公平鎖:
    
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;
        final void lock() {
            acquire(1);
          //	acquire方法 -> tryAcquire(arg) -> protected boolean tryAcquire(int arg)
          //	tryAcquire是父類定義的,這里使用了模版設(shè)計(jì)模式
          //	見下面的函數(shù):2.1
        }
        protected final boolean tryAcquire(int acquires) {	//	tryAcquire的實(shí)現(xiàn)
            final Thread current = Thread.currentThread();
            int c = getState();		//	獲取狀態(tài)位
            if (c == 0) {		
                if (!hasQueuedPredecessors() && 		//	公平鎖分支,公平與非公平就這里不一樣,詳細(xì)在下面2.2
                    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;
        }
    }
    
    2.1 
    //	父類不實(shí)現(xiàn),下放到子類實(shí)現(xiàn)
    //	子類有很多實(shí)現(xiàn)類,這里參考FairSync的實(shí)現(xiàn),代碼在上面
    protected boolean tryAcquire(int arg) {
         throw new UnsupportedOperationException();
    }
    
    2.2 
    //	hasQueuedPredecessors
    //	邏輯很簡(jiǎn)單,就是判斷一下隊(duì)列前面是否有排隊(duì)線程,如果返回true,說(shuō)明有一個(gè)排隊(duì)的線程;返回false說(shuō)明這個(gè)線程是隊(duì)列的頭
    public final boolean hasQueuedPredecessors() {
        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
        return h != t && ((s = h.next) == null || s.thread != Thread.currentThread());
    }

    接下來(lái)以非公平鎖為突破口:

  5. 1. 對(duì)比公平鎖和非公平鎖的 tryAcquire()方法的實(shí)現(xiàn)代碼,其實(shí)差別就在于非公平鎖獲取鎖時(shí)比公平鎖中少了一個(gè)判斷hasQuevedPredecessors()

  6. 2. hasQueuedPredecessors() 中判斷了是否需要排隊(duì),導(dǎo)致公平鎖和非公平鎖的差異如下:

    1. 1. 公平鎖:公平鎖講究先來(lái)先到,線程在獲取鎖時(shí)如果這個(gè)鎖的等待隊(duì)列中己經(jīng)有線程在等待,那么當(dāng)前線程會(huì)進(jìn)入等待隊(duì)列中

    2. 2. 非公平鎖:不管是否有等待隊(duì)列,如果可以獲取鎖,則立刻占有鎖對(duì)象。也就是說(shuō)隊(duì)列的第一個(gè)排隊(duì)線程蘇醒后,不一定就是排頭的這個(gè)線程得鎖,它還是需要參加競(jìng)爭(zhēng)鎖(存在線程競(jìng)爭(zhēng)的情況下),后來(lái)的線程可能不講武德插隊(duì)奪鎖了。

AQS源碼分析——以ReentrantLock為例?

?

引出源碼三部曲:

  1. 1. tryAcquire

  2. 2. addWaiter

  3. 3. acquireQueued

lock方法:

//	對(duì)比公平與非公平的lock方法:

//	公平鎖lock
final void lock() {
    acquire(1);
}


//	非公平鎖
final void lock() {
    if (compareAndSetState(0, 1))			//	CAS操作直接搶鎖
        setExclusiveOwnerThread(Thread.currentThread());	//	設(shè)置擁有獨(dú)占量的線程
    else
        acquire(1);		//	搶不到再去排隊(duì)
}
//	這里非公平的復(fù)雜,我們看非公平鎖的代碼:

acquire三大流向:

AQS源碼分析——以ReentrantLock為例

?

1.0 acquire方法
//	公平與非公平的acquire方法一樣的
public final void acquire(int arg) {
    if (!tryAcquire(arg) &&		//	tryAcquire方法是再次嘗試搶一下鎖,看看是否空閑或者自己持有鎖,具體實(shí)現(xiàn)在前面的代碼里。這里如果失敗就是false,取反就是true,繼續(xù)往下走,執(zhí)行addWaiter
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))	//	Node.EXCLUSIVE表示獨(dú)占排他
        selfInterrupt();
}


2.0 tryAcquire方法
//	acquire方法第一個(gè)執(zhí)行的方法,也是分支的第一支
//	頂層父類并未實(shí)現(xiàn)改方法,AQS類中
protected boolean tryAcquire(int arg) {
    throw new UnsupportedOperationException();
}
//	公平鎖和非公平鎖都對(duì)此方法進(jìn)行了實(shí)現(xiàn),非公平只是缺少了hasQueuedPredecessors()方法,代碼在前面有展示


3.0 addWaiter方法
//	如果執(zhí)行2.0搶鎖失敗

private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);		//	封裝線程,進(jìn)入隊(duì)列
    Node pred = tail;		//	設(shè)置前置為tail
    if (pred != null) {	//	如果pred不為空,意思就是不是隊(duì)列的第一個(gè)元素,執(zhí)行下列操作
        node.prev = pred;			//	更新前置節(jié)點(diǎn)
        if (compareAndSetTail(pred, node)) {	// 3.0.1CAS的修改尾部元素,并且直接返回node,不再執(zhí)行enq入隊(duì)操作
            pred.next = node;
            return node;
        }
    }
    enq(node);	//	進(jìn)入隊(duì)列,當(dāng)且僅當(dāng)node是pred==null時(shí)才會(huì)執(zhí)行
    return node;
}

3.1 enq方法:
//	入隊(duì)操作:
private Node enq(final Node node) {
    for (;;) {
        Node t = tail;
        if (t == null) { // 如果tail為空,則需要初始化,這里頭節(jié)點(diǎn)并沒有使用實(shí)參node,而是new了一個(gè)空節(jié)點(diǎn),
            if (compareAndSetHead(new Node()))	//	CAS的修改隊(duì)首,期望值為null,改為空節(jié)點(diǎn),也叫虛擬節(jié)點(diǎn),作用就是站位
                tail = head;		//	將頭尾指針都指向這個(gè)節(jié)點(diǎn)
        } else {					//	如果tail不為空(可能一開始tail為空,但是是一個(gè)for true循環(huán),第一次初始化之后就會(huì)走這一步)
            node.prev = t;		//	將t設(shè)置為node節(jié)點(diǎn)的前置節(jié)點(diǎn),
            if (compareAndSetTail(t, node)) {		//CAS的修改尾節(jié)點(diǎn),這部分代碼邏輯和3.0.1 邏輯一樣
                t.next = node;
                return t;
            }
        }
    }//	注意這是個(gè)循環(huán),保證這個(gè)里面一定會(huì)執(zhí)行到else,
}

4.0 acquireQueued方法
//	解釋了線程節(jié)點(diǎn)如何在隊(duì)列里自旋
final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;	//	中斷標(biāo)記
        for (;;) {
            final Node p = node.predecessor();	//	獲取當(dāng)前節(jié)點(diǎn)的前置節(jié)點(diǎn)
            if (p == head && tryAcquire(arg)) {	//	如果前置節(jié)點(diǎn)是head,再次嘗試獲取搶鎖
                setHead(node);		//	細(xì)節(jié)見4.1 
                p.next = null; 		// 	意思是將獲取到鎖的節(jié)點(diǎn)變成虛擬頭節(jié)點(diǎn),之前的虛擬頭節(jié)點(diǎn)廢棄掉,直接GC
                failed = false;		//	入隊(duì)成功,則改為false
                return interrupted;
            }
            if (shouldParkAfterFailedAcquire(p, node) && 	//	細(xì)節(jié)見4.2 既改變狀態(tài),又返回boolean值
                parkAndCheckInterrupt())	//	細(xì)節(jié)見4.3  等待lockSupport發(fā)放許可
                interrupted = true;			//	修改interrupted為true
        }
    } finally {
        if (failed)		//	如果入隊(duì)失敗,則取消排隊(duì)
            cancelAcquire(node);
    }
}

4.1 setHead
  
private void setHead(Node node) {
    head = node;
    node.thread = null;
    node.prev = null;
}


4.2 shouldParkAfterFailedAcquire方法
//	
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { //	此處pred就是head節(jié)點(diǎn)
    int ws = pred.waitStatus;		//	head節(jié)點(diǎn)狀態(tài)默認(rèn)為wait 0
    if (ws == Node.SIGNAL)			//	如果是-1則執(zhí)行
        return true;
    if (ws > 0) {								//	大于0
        do {
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else {									//	status = 0跑到這里來(lái)
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);		//	后面的節(jié)點(diǎn)將他前面的節(jié)點(diǎn)status改為-1
    }
    return false;
}


4.3 parkAndCheckInterrupt
//	發(fā)放許可并不是卡住線程的關(guān)鍵,他只是保證,進(jìn)入隊(duì)列的線程節(jié)點(diǎn)一定是按照順序一個(gè)個(gè)執(zhí)行的
private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);					//	從acquireQueued方法過(guò)來(lái),如果沒有獲得許可就一直在這卡著
    return Thread.interrupted();		//	正常執(zhí)行,沒有意外或被打斷就是false,跳轉(zhuǎn)到4.0中繼續(xù)
}

AQS源碼分析——以ReentrantLock為例

?unlock方法:

0.0 unlock
//	
public void unlock() {
    sync.release(1);
}

1.0 release
//	釋放鎖
public final boolean release(int arg) {
    if (tryRelease(arg)) {		//	細(xì)節(jié)見1.1 此時(shí)執(zhí)行結(jié)果為true
        Node h = head;		//	獲取頭節(jié)點(diǎn)
        if (h != null && h.waitStatus != 0)		//	頭節(jié)點(diǎn)不等于null,且頭節(jié)點(diǎn)wait!=0,(之前修改為SIGNAL -1)
            unparkSuccessor(h);	//	細(xì)節(jié)見1.2,傳入?yún)?shù)為頭節(jié)點(diǎn)
        return true;
    }
    return false;
}

1.1 
//	tryRelease
protected final boolean tryRelease(int releases) {	// releases = 1	
    int c = getState() - releases;	//	c =0
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {		//	進(jìn)入這里
        free = true;		//	free = true
        setExclusiveOwnerThread(null);
    }
    setState(c);
    return free;			//	返回true
}


1.2 unparkSuccessor
//	
private void unparkSuccessor(Node node) {
    int ws = node.waitStatus;
    if (ws < 0)		
        compareAndSetWaitStatus(node, ws, 0);		//	頭節(jié)點(diǎn)進(jìn)來(lái)之后,會(huì)將wait的-1改為0

    Node s = node.next;		//	獲取頭節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),即第一個(gè)真實(shí)任務(wù)節(jié)點(diǎn)
    if (s == null || s.waitStatus > 0) {		//		節(jié)點(diǎn)不為null,不進(jìn)來(lái)
        s = null;					
        for (Node t = tail; t != null && t != node; t = t.prev)
            if (t.waitStatus <= 0)
                s = t;
    }
    if (s != null)		//	節(jié)點(diǎn)不為null,進(jìn)入這里
        LockSupport.unpark(s.thread);		//	給線程節(jié)點(diǎn)發(fā)放許可,繼續(xù)進(jìn)入到1.0中;此處受影響的還有acquire方法代碼塊的4.3
				//	不過(guò)發(fā)放許可并不代表中一定是這個(gè)線程獲取鎖,這就是非公平鎖的精髓,總會(huì)有不講武德插隊(duì)的,獲取許可只是有獲取鎖的可能,是否真的獲取到還要看能否搶到鎖。這里發(fā)放許可,使得被park的線程喚醒了,可以去tryAcquire操作,依然可能會(huì)失敗,繼續(xù)被阻塞
  			//		這里如果不使用park和unpark,則會(huì)一直執(zhí)行for,導(dǎo)致cpu負(fù)載過(guò)重
}

異常情況

模擬某個(gè)線程不想等待了,想取消排隊(duì)

  1. 1. 隊(duì)尾元素離開

  2. 2. 隊(duì)中間的元素離開

  3. 3. 隊(duì)中間多個(gè)元素離開

    1.0 cancelAcquire方法
    //	取消入隊(duì)
    private void cancelAcquire(Node node) {
        // Ignore if node doesn't exist
        if (node == null)
            return;
    
        node.thread = null;		//	將線程賦值null
    
        Node pred = node.prev;	//	獲取前一個(gè)節(jié)點(diǎn)
        while (pred.waitStatus > 0)		//	waitStatus>0意思就是取消狀態(tài),一直向前獲取到一個(gè)不會(huì)取消的頭節(jié)點(diǎn),
            node.prev = pred = pred.prev;		//	最壞情況就是獲取到虛擬頭節(jié)點(diǎn)
    
        Node predNext = pred.next;		//	前置節(jié)點(diǎn)的next指向當(dāng)前節(jié)點(diǎn)的next
    
        node.waitStatus = Node.CANCELLED;		//	狀態(tài)設(shè)置為取消
    
        if (node == tail && compareAndSetTail(node, pred)) {		//	如果node是隊(duì)尾節(jié)點(diǎn),CAS將pre節(jié)點(diǎn)設(shè)置為尾節(jié)點(diǎn)
            compareAndSetNext(pred, predNext, null);		//	同時(shí)CAS設(shè)置pred節(jié)點(diǎn)的next為null
        } else {					//	如果不是隊(duì)尾節(jié)點(diǎn)
            int ws;
            if (pred != head &&		//	如果前置節(jié)點(diǎn)不是頭節(jié)點(diǎn)且
                ((ws = pred.waitStatus) == Node.SIGNAL ||	//前置節(jié)點(diǎn)的狀態(tài)為-1或狀態(tài)小于0并且修改為-1成功
                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&	
                pred.thread != null) {	//	且pred線程不為空
                Node next = node.next;	//	獲取當(dāng)前節(jié)點(diǎn)的next	
                if (next != null && next.waitStatus <= 0)		//	next不為空且status<=0時(shí)
                    compareAndSetNext(pred, predNext, next);
            		} else {
                unparkSuccessor(node);
            }
            node.next = node; // help GC
        }
    }

    ?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-499790.html

到了這里,關(guān)于AQS源碼分析——以ReentrantLock為例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 萬(wàn)字長(zhǎng)文硬核AQS源碼分析

    萬(wàn)字長(zhǎng)文硬核AQS源碼分析

    閱讀本文前,需要儲(chǔ)備的知識(shí)點(diǎn)如下,點(diǎn)擊鏈接直接跳轉(zhuǎn)。 java線程詳解 Java不能操作內(nèi)存?Unsafe了解一下 一文讀懂LockSupport AQS即 AbstractQueuedSynchronizer 的簡(jiǎn)稱,翻譯過(guò)來(lái)就是抽象隊(duì)列同步器的意思,由Doug Lea大神開發(fā)的。說(shuō)他抽象是因?yàn)樗峁┑氖且粋€(gè)基于隊(duì)列的同步器框架

    2024年02月11日
    瀏覽(16)
  • 如何排查 IDEA 自身報(bào)錯(cuò)?| 以 IntelliJ IDEA 2023.1.4 無(wú)法刷新項(xiàng)目 Maven 模塊的問題為例

    如何排查 IDEA 自身報(bào)錯(cuò)?| 以 IntelliJ IDEA 2023.1.4 無(wú)法刷新項(xiàng)目 Maven 模塊的問題為例

    這個(gè)問題是 2023 年 7 月 26 日遇到的,當(dāng)時(shí)還是 IDEA 2023.1.4,結(jié)果文章還沒寫完,7 月 27 日自動(dòng)給更新了 IDEA 2023.2。問題估計(jì)解決了。 所以,本文就簡(jiǎn)單提一下 IDEA 自身報(bào)錯(cuò)的排查方法。 先說(shuō)問題怎么處理: IDEA 設(shè)置從 Maven wrapper 改為使用內(nèi)置 Maven。 Maven 項(xiàng)目模塊調(diào)整后,

    2024年02月15日
    瀏覽(293)
  • Godot 4 源碼分析 - 獲取屬性信息

    Godot 4 源碼分析 - 獲取屬性信息

    在管道通信基礎(chǔ)上,可進(jìn)行宿主程序與Godot的雙向通信。 先拿屬性信息試試手。 ?這已具備RTTI的雛形。?

    2024年02月16日
    瀏覽(30)
  • 萬(wàn)字長(zhǎng)文解析AQS抽象同步器核心原理(深入閱讀AQS源碼)

    萬(wàn)字長(zhǎng)文解析AQS抽象同步器核心原理(深入閱讀AQS源碼)

    在爭(zhēng)用激烈的場(chǎng)景下使用基于CAS自旋實(shí)現(xiàn)的輕量級(jí)鎖有兩個(gè)大的問題: CAS惡性空自旋會(huì)浪費(fèi)大量的CPU資源。 在SMP架構(gòu)的CPU上會(huì)導(dǎo)致“總線風(fēng)暴”。 解決CAS惡性空自旋的有效方式之一是以空間換時(shí)間,較為常見的方案有兩種:分散操作熱點(diǎn)、使用隊(duì)列削峰。 JUC并發(fā)包使用的是

    2024年02月11日
    瀏覽(20)
  • java基礎(chǔ)-并發(fā)編程-ReentrantLock源碼學(xué)習(xí)
  • 并發(fā)編程 - AQS 源碼

    1. AQS 源碼 2.?AQS 框架具體實(shí)現(xiàn) - 獨(dú)占鎖實(shí)現(xiàn) ReentrantLock 源碼 實(shí)現(xiàn) ReentrantLock 的三大核心原理: LocksSuport :加鎖解鎖 自旋 :如果沒有加鎖成功就一直自旋 CAS :保證只能有一個(gè)線程可以加鎖成功 queue 隊(duì)列:用容器保存上面未加鎖成功的阻塞線程,要解鎖的時(shí)候從容器中拿出

    2023年04月21日
    瀏覽(20)
  • Java多線程/AQS源碼

    持鎖模式-資源占用模式: ? 你是想要群體面試,還是單獨(dú)面試啊 ? 獨(dú)占和共享 獲鎖方式: ? 是不是要把手機(jī)關(guān)機(jī)啊,趕不趕時(shí)間是不是必須要在某個(gè)時(shí)間內(nèi)面試完,是否公平啊 ? 不響應(yīng)線程中斷;響應(yīng)線程中斷;定時(shí)獲取鎖;公平獲取;非公平獲取 同步狀態(tài)-鎖狀態(tài);

    2024年02月15日
    瀏覽(16)
  • JUC源碼系列-AQS獨(dú)占鎖獲取

    JUC源碼系列-AQS獨(dú)占鎖獲取

    AQS(AbstractQueuedSynchronizer)是JAVA中眾多鎖以及并發(fā)工具的基礎(chǔ),其底層采用樂觀鎖,大量使用了CAS操作, 并且在沖突時(shí),采用自旋方式重試,以實(shí)現(xiàn)輕量級(jí)和高效地獲取鎖。 AQS雖然被定義為抽象類,但事實(shí)上它并不包含任何抽象方法。這是因?yàn)锳QS是被設(shè)計(jì)來(lái)支持多種用途的

    2023年04月16日
    瀏覽(21)
  • 【源碼解析】從Conditon角度聊聊AQS原理

    【源碼解析】從Conditon角度聊聊AQS原理

    前幾篇文章,我們?cè)敿?xì)描述了線程池的原理以及核心代碼,以及阻塞隊(duì)列,ReentrantLock的核心流程,本篇主要介紹下lock鎖中的condition 非公平鎖 非公平鎖,會(huì)先進(jìn)行CAS獲取鎖,搶到了就直接返回。 condition需要依賴于ReentrantLock,調(diào)用await 進(jìn)入等待或者是singale喚醒,都需要獲取鎖

    2024年02月04日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包