成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JAVA并發(fā)編程之-ReentrantLock鎖原理解讀

荊兆峰 / 1559人閱讀

摘要:作者畢來(lái)生微信鎖狀態(tài)轉(zhuǎn)換分類(lèi)以后幫助我們提供了線(xiàn)程同步機(jī)制,通過(guò)顯示定義同步鎖來(lái)實(shí)現(xiàn)對(duì)象之間的同步。等待重新嘗試因?yàn)樵谥惺怯藐P(guān)鍵字聲明的,故可以在線(xiàn)程間可見(jiàn)再次判斷一下能否持有鎖可能線(xiàn)程同步代碼執(zhí)行得比較快,已經(jīng)釋放了鎖,不可以就返回。

作者 : 畢來(lái)生
微信: 878799579
鎖狀態(tài)轉(zhuǎn)換

Lock分類(lèi)

? Jdk1.5以后幫助我們提供了線(xiàn)程同步機(jī)制,通過(guò)顯示定義同步鎖來(lái)實(shí)現(xiàn)對(duì)象之間的同步。還是Doug Lea這個(gè)家伙寫(xiě)的。相信讀過(guò)源碼的人在很多地方都可以看到這個(gè)家伙。

? Lock可以顯示的進(jìn)行加鎖,解鎖。但是每次只能有一個(gè)線(xiàn)程對(duì)Lock對(duì)象加鎖

? Lock實(shí)現(xiàn)結(jié)構(gòu)如下圖所示:

? 按照使用的常用度,分別標(biāo)注了(1),(2),(3)。接下來(lái)我們就主要學(xué)習(xí)一下ReentrantLock的使用

可重入鎖

? ReentrantLock實(shí)現(xiàn)的前提就是AbstractQueuedSynchronizer,簡(jiǎn)稱(chēng)AQS.。核心方法內(nèi)部實(shí)現(xiàn)均在A(yíng)QS中,后續(xù)我們?cè)谠敿?xì)解讀AQS相關(guān)知識(shí)點(diǎn)以及使用場(chǎng)景。我們先來(lái)看一段偽代碼用以表述可重入鎖的使用情況。接下來(lái)我們來(lái)詳細(xì)分析獲取鎖以及釋放鎖內(nèi)部實(shí)現(xiàn)到底做了什么事情。

package org.bilaisheng.juc;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: bilaisheng
 * @Wechat: 878799579
 * @Date: 2019/1/3 22:55
 * @Todo: 偽代碼僅演示使用
 * @Version : JDK11 , IDEA2018
 */
public class ReentrantLockTest {


    public static void main(String[] args) {
        Lock lock = new ReentrantLock();

        // 獲取鎖
        lock.lock();
        
        // access the resource protected by this lock
        // do something
        
        // 釋放鎖
        lock.unlock();

    }
}
Sync對(duì)象剖析
     /** Synchronizer providing all implementation mechanics */
    private final Sync sync;

    /**
     * Base of synchronization control for this lock. Subclassed
     * into fair and nonfair versions below. Uses AQS state to
     * represent the number of holds on the lock.
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        // xxxx
    }    

他會(huì)根據(jù)傳入構(gòu)造方法的布爾類(lèi)型參數(shù)實(shí)例化出Sync的實(shí)現(xiàn)類(lèi)FairSync和NoFairSync。

FairSync: 公平的Sync

NoFairSync : 不公平的Sync

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}
ReentrantLock.lock()實(shí)現(xiàn)原理

? 我們用的比較多的ReentrantLock是非公平鎖,我們來(lái)用一張圖來(lái)分析一下看看它是如何實(shí)現(xiàn)的。

上圖就做了兩件事情:

1、設(shè)置AbstractQueuedSynchronizer的state為1

2、設(shè)置AbstractOwnableSynchronizer的thread為當(dāng)前線(xiàn)程

線(xiàn)程A正在執(zhí)行中,status = 1。

線(xiàn)程B嘗試?yán)肅AS去判斷state是不是0,是0就設(shè)置為1,當(dāng)然這一步操作肯定是失敗的,因?yàn)榫€(xiàn)程A已經(jīng)將state設(shè)置成了1,所以此時(shí)肯定是失敗的。

失敗了之后進(jìn)入FIFO等待隊(duì)列。等待重新嘗試

/**
 * Performs non-fair tryLock.  tryAcquire is implemented in
 * subclasses, but both need nonfair try for trylock method.
 */
@ReservedStackAccess
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;
}

因?yàn)樵贏(yíng)bstractQueuedSynchronizer中state是用volatile關(guān)鍵字聲明的,故可以在線(xiàn)程間可見(jiàn)

/**
 * The synchronization state.
 */
private volatile int state;

再次判斷一下能否持有鎖(可能線(xiàn)程A同步代碼執(zhí)行得比較快,已經(jīng)釋放了鎖),不可以就返回false。

根據(jù)上方代碼可以看出同一個(gè)鎖最多能重入Integer.MAX_VALUE次,也就是2147483647。

ReentrantLock.unLock()實(shí)現(xiàn)原理

此處較為簡(jiǎn)單。附上調(diào)用關(guān)系鏈路

// 步驟一
public void unlock() {
    sync.release(1);
}

// 步驟二 : AbstractQueuedSynchronizer
public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
           unparkSuccessor(h);
        return true;
    }
    return false;
}

//步驟二 : ReentrantLock
 @ReservedStackAccess
protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    setState(c);
    return free;
}

當(dāng)一條線(xiàn)程對(duì)同一個(gè)ReentrantLock全部解鎖之后,AQS的state就是0了,AbstractOwnableSynchronizer的exclusiveOwnerThread將被設(shè)置為null,這樣就表示沒(méi)有線(xiàn)程占有鎖,方法返回true。

喜歡就關(guān)注我吧

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75675.html

相關(guān)文章

  • 手撕面試官系列(七):面試必備常問(wèn)并發(fā)編程高級(jí)面試專(zhuān)題

    摘要:如何在線(xiàn)程池中提交線(xiàn)程內(nèi)存模型相關(guān)問(wèn)題什么是的內(nèi)存模型,中各個(gè)線(xiàn)程是怎么彼此看到對(duì)方的變量的請(qǐng)談?wù)動(dòng)惺裁刺攸c(diǎn),為什么它能保證變量對(duì)所有線(xiàn)程的可見(jiàn)性既然能夠保證線(xiàn)程間的變量可見(jiàn)性,是不是就意味著基于變量的運(yùn)算就是并發(fā)安全的請(qǐng)對(duì)比下對(duì)比的異同。 并發(fā)編程高級(jí)面試面試題 showImg(https://upload-images.jianshu.io/upload_images/133416...

    Charles 評(píng)論0 收藏0
  • 后臺(tái)開(kāi)發(fā)常問(wèn)面試題集錦(問(wèn)題搬運(yùn)工,附鏈接)

    摘要:基礎(chǔ)問(wèn)題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線(xiàn)抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類(lèi)與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類(lèi)對(duì)象鎖和類(lèi)鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類(lèi)單例模式和 Java基礎(chǔ)問(wèn)題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    spacewander 評(píng)論0 收藏0
  • 后臺(tái)開(kāi)發(fā)常問(wèn)面試題集錦(問(wèn)題搬運(yùn)工,附鏈接)

    摘要:基礎(chǔ)問(wèn)題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線(xiàn)抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類(lèi)與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類(lèi)對(duì)象鎖和類(lèi)鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類(lèi)單例模式和 Java基礎(chǔ)問(wèn)題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    xfee 評(píng)論0 收藏0
  • 后臺(tái)開(kāi)發(fā)常問(wèn)面試題集錦(問(wèn)題搬運(yùn)工,附鏈接)

    摘要:基礎(chǔ)問(wèn)題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線(xiàn)抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類(lèi)與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類(lèi)對(duì)象鎖和類(lèi)鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類(lèi)單例模式和 Java基礎(chǔ)問(wèn)題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    makeFoxPlay 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<