最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java?LockSupport實(shí)現(xiàn)原理示例解析

 更新時(shí)間:2023年01月09日 09:19:53   作者:小海編碼日記  
這篇文章主要為大家介紹了java?LockSupport實(shí)現(xiàn)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

前文中了解到AQS借助LockSupport.park和LockSupport.unpark完成線程的阻塞和喚醒,那么LockSupport內(nèi)部又是怎么實(shí)現(xiàn)的?這是一個(gè)什么類?

LockSupport是用于使用鎖阻塞線程的基礎(chǔ)實(shí)現(xiàn),是其他同步類的基礎(chǔ),這個(gè)類為每個(gè)使用它的線程關(guān)聯(lián)一個(gè)許可證(有點(diǎn)類似于Semaphore),如果許可證可用,線程調(diào)用park方法時(shí)會(huì)立即返回,線程正常執(zhí)行,否則當(dāng)前線程阻塞,直到有其他線程調(diào)用unpark使得許可證可用,此時(shí)線程被喚醒,再次嘗試獲取許可證,其內(nèi)部定義的park和unpark方法提供了阻塞和解決阻塞的基本實(shí)現(xiàn)。

LockSupport常見函數(shù)

如下表所示:

函數(shù)名稱說(shuō)明備注
void park()阻塞當(dāng)前線程在下列情況發(fā)生時(shí)喚醒: 1.調(diào)用unpark函數(shù),釋放該線程的許可; 2.該線程被中斷; 3.設(shè)置的阻塞超時(shí)時(shí)間耗盡; 4.到達(dá)設(shè)置的指定時(shí)間
void park(Object blocker)使用指定的blocker對(duì)象阻塞當(dāng)前線程喚醒條件,park中已說(shuō)明
void parkNanos(long nanos)阻塞當(dāng)前線程直到超時(shí)時(shí)間耗盡,nanos為指定的超時(shí)時(shí)間喚醒條件,park中已說(shuō)明
void parkNanos(Object blocker, long nanos)在超時(shí)時(shí)間耗盡前,使用指定的blocker對(duì)象阻塞當(dāng)前線程,如果在到達(dá)超時(shí)時(shí)間后,許可仍不可用,則結(jié)束阻塞喚醒條件,park中已說(shuō)明
void parkUntil(long deadline)在指定時(shí)間前,阻塞該線程,如果在到達(dá)指定時(shí)間后,許可仍不可用,則結(jié)束阻塞喚醒條件,park中已說(shuō)明
void parkUntil(Object blocker, long deadline)在指定時(shí)間前,使用指定的對(duì)象阻塞該線程,如果在到達(dá)指定時(shí)間后,許可仍不可用,則結(jié)束阻塞喚醒條件,park中已說(shuō)明
void unpark(Thread thread)用于喚醒傳入的在阻塞中的線程/
Object getBlocker(Thread t)獲取當(dāng)前線程的阻塞對(duì)象/
void setBlocker(Thread t, Object arg)使用指定對(duì)象為線程設(shè)置阻塞對(duì)象/

LockSupport.park

ReentrantLock中調(diào)用LockSupport.park代碼如下所示:

 // AbstractQueuedSynchronizer.java
 private final boolean parkAndCheckInterrupt() {
     LockSupport.park(this);
     return Thread.interrupted();
 }

在LockSupport中,void park(Object blocker)實(shí)現(xiàn)代碼如下:

 // LockSupport.java
 public static void park(Object blocker) {
     Thread t = Thread.currentThread();
     setBlocker(t, blocker);
     UNSAFE.park(false, 0L);
     setBlocker(t, null);
 }

可以看到在park流程中主要包含以下過程:

獲取當(dāng)前線程

將傳入的對(duì)象設(shè)置為該線程的parkBlocker

setBlocker函數(shù)實(shí)現(xiàn)如下所示:

 private static void setBlocker(Thread t, Object arg) {
     // Even though volatile, hotspot doesn't need a write barrier here.
     UNSAFE.putObject(t, parkBlockerOffset, arg);
 }

可以看到這里新出現(xiàn)了UNSAFE和parkBlockerOffset兩個(gè)標(biāo)識(shí),這兩個(gè)是用來(lái)干嘛的?我們一起看看其聲明的代碼:

 private static final sun.misc.Unsafe UNSAFE;
 private static final long parkBlockerOffset;
 static {
     try {
         UNSAFE = sun.misc.Unsafe.getUnsafe();
         Class<?> tk = Thread.class;
         parkBlockerOffset = UNSAFE.objectFieldOffset
             (tk.getDeclaredField("parkBlocker"));
         .....
     } catch (Exception ex) { throw new Error(ex); }
 }

可以看到UNSAFE對(duì)象是通過Unsafe.getUnsafe()獲取的,那么Unsafe這個(gè)類到底是干嘛的?

大家都知道Java對(duì)象在內(nèi)存中創(chuàng)建,大多數(shù)情況下我們都是通過類的對(duì)象去修改和訪問內(nèi)存中的數(shù)據(jù)的,那么如果需要直接從內(nèi)存修改某一對(duì)象的取值,應(yīng)該怎么做呢?就是使用Unsafe類,該類只允許在JDK信任的類中調(diào)用(當(dāng)前也可以用反射實(shí)例化該類對(duì)象)。

在Unsafe類中定義了兩個(gè)重要函數(shù)park和unpark,其中park用于實(shí)現(xiàn)線程阻塞,unpark用于實(shí)現(xiàn)線程喚醒(Unsafe本質(zhì)上是操作線程的Parker對(duì)象來(lái)完成線程阻塞和喚醒的,具體見參考鏈接,了解即可),上文中的parkBlockerOffset正是定義了Thread類的parkBlocker屬性成員的內(nèi)存偏移量,使用該值再結(jié)合Unsafe對(duì)象就可以實(shí)現(xiàn)直接操作內(nèi)存中的parkBlocker值的目的,Thread類中的parkBlocker聲明如下:

 // Thread.java
 volatile Object parkBlocker;

可以得到這一環(huán)節(jié)主要是將AQS作為blocker設(shè)置到當(dāng)前線程的parkBlocker成員屬性上。

CAS底層也是通過Unsafe執(zhí)行的

執(zhí)行UNSAFE.park

結(jié)合上文可知,這步完成后,當(dāng)前線程阻塞

設(shè)置線程的parkBlocker為null

第三步中線程處于阻塞狀態(tài),當(dāng)然就不能執(zhí)行設(shè)置parkBlocker為null的操作了,那么什么時(shí)候執(zhí)行呢?當(dāng)線程從阻塞狀態(tài)喚醒時(shí),執(zhí)行該步驟,使得線程的parkBlocker對(duì)象恢復(fù)初始狀態(tài)。

LockSupport.unpark

LockSupport.unpark代碼如下所示:

 // LockSupport.java
 public static void unpark(Thread thread) {
     if (thread != null)
         UNSAFE.unpark(thread);
 }

可以看出當(dāng)傳入的線程不為空時(shí),執(zhí)行Unsafe的park函數(shù)喚醒當(dāng)前線程,取消阻塞,此時(shí)繼續(xù)執(zhí)行park函數(shù)中的setBlocker(null),將parkBlocker成員設(shè)置為null。

參考鏈接  http://www.fzitv.net/article/272073.htm

以上就是java LockSupport實(shí)現(xiàn)原理示例解析的詳細(xì)內(nèi)容,更多關(guān)于java LockSupport原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MyBatis注解實(shí)現(xiàn)動(dòng)態(tài)SQL問題

    MyBatis注解實(shí)現(xiàn)動(dòng)態(tài)SQL問題

    這篇文章主要介紹了MyBatis注解實(shí)現(xiàn)動(dòng)態(tài)SQL問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • SpringBoot使用spring.config.import多種方式導(dǎo)入配置文件

    SpringBoot使用spring.config.import多種方式導(dǎo)入配置文件

    本文主要介紹了SpringBoot使用spring.config.import多種方式導(dǎo)入配置文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Maven配置文件修改及導(dǎo)入第三方j(luò)ar包的實(shí)現(xiàn)

    Maven配置文件修改及導(dǎo)入第三方j(luò)ar包的實(shí)現(xiàn)

    本文主要介紹了Maven配置文件修改及導(dǎo)入第三方j(luò)ar包的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Springboot項(xiàng)目異常處理及返回結(jié)果統(tǒng)一

    Springboot項(xiàng)目異常處理及返回結(jié)果統(tǒng)一

    這篇文章主要介紹了Springboot項(xiàng)目異常處理及返回結(jié)果統(tǒng)一,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • Java編程使用卡片布局管理器示例【基于swing組件】

    Java編程使用卡片布局管理器示例【基于swing組件】

    這篇文章主要介紹了Java編程使用卡片布局管理器,結(jié)合實(shí)例形式分析了java基于swing組件的卡片布局管理器具體實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2018-01-01
  • Java中Thread類基本用法詳解

    Java中Thread類基本用法詳解

    Java中的Thread類是用于創(chuàng)建和管理線程的類,Thread類提供了許多方法來(lái)管理線程,包括啟動(dòng)線程、中斷線程、暫停線程等,下面這篇文章主要給大家介紹了關(guān)于Java中Thread類基本用法的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Maven發(fā)布Jar包中文亂碼解決方法

    Maven發(fā)布Jar包中文亂碼解決方法

    這篇文章主要介紹了Maven發(fā)布Jar包中文亂碼解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java實(shí)現(xiàn)讀取設(shè)置pdf屬性信息

    Java實(shí)現(xiàn)讀取設(shè)置pdf屬性信息

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)讀取設(shè)置pdf屬性信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證淺析

    Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證淺析

    因?yàn)镴ava在安裝的時(shí)候,會(huì)默認(rèn)導(dǎo)入某些根證書,所以有些網(wǎng)站不導(dǎo)入證書,也可以使用Java進(jìn)行訪問,這篇文章主要給大家介紹了關(guān)于Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • 基于Java實(shí)現(xiàn)簡(jiǎn)單的時(shí)序數(shù)據(jù)壓縮算法

    基于Java實(shí)現(xiàn)簡(jiǎn)單的時(shí)序數(shù)據(jù)壓縮算法

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單易懂的時(shí)序數(shù)據(jù)壓縮算法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06

最新評(píng)論

江阴市| 麻城市| 望江县| 望都县| 保靖县| 乌恰县| 长兴县| 龙南县| 巫山县| 崇文区| 卓资县| 明光市| 德清县| 政和县| 东方市| 基隆市| 拜泉县| 开鲁县| 永年县| 丰原市| 搜索| 阳曲县| 双城市| 淮阳县| 建湖县| 柳河县| 东阿县| 龙泉市| 阳泉市| 横山县| 乌鲁木齐县| 萝北县| 阿拉尔市| 桐庐县| 芷江| 辛集市| 黄平县| 安达市| 塔城市| 康乐县| 宜黄县|