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

Java中的ReentrantLock實(shí)現(xiàn)原理及代碼演示

 更新時(shí)間:2024年01月13日 09:39:17   作者:java架構(gòu)師-太陽(yáng)  
這篇文章主要介紹了Java中的ReentrantLock實(shí)現(xiàn)原理及代碼演示,非公平鎖 如果已經(jīng)進(jìn)入隊(duì)列,鏈表里面的線(xiàn)程是先進(jìn)先出,如果已經(jīng)釋放了鎖,在搶占鎖時(shí),鏈表里面的頭結(jié)點(diǎn)和還沒(méi)有入隊(duì)列的線(xiàn)程搶鎖,需要的朋友可以參考下

介紹

互斥鎖 實(shí)現(xiàn)Lock接口 并且最好在 finally 塊中釋放

公平鎖 非公平鎖 如果已經(jīng)進(jìn)入隊(duì)列,鏈表里面的線(xiàn)程是先進(jìn)先出,如果已經(jīng)釋放了鎖,在搶占鎖時(shí),鏈表里面的頭結(jié)點(diǎn)和還沒(méi)有入隊(duì)列的線(xiàn)程搶鎖

使用代碼

public class Test {
    public static void main(String[] args) {
       Task task = new Task();
       for(int i = 0; i < 10; i++) {
          new Thread(task).start();
       }
    }
}
class Task implements Runnable {
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
        lock.lock();
        try {
            Thread.sleep(1000);
            System.out.println("業(yè)務(wù)代碼");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

實(shí)現(xiàn)原理

采用AQS+CAS+LockSupport用來(lái)阻塞和喚醒線(xiàn)程)

ReentrantLock有三類(lèi)內(nèi)部類(lèi),實(shí)現(xiàn)都在其內(nèi)部類(lèi)Sync中,默認(rèn)是使用非公平鎖NonFairSync。

非公平鎖可提高效率,在可重入鎖時(shí)可以減少線(xiàn)程切換開(kāi)銷(xiāo)。可以通過(guò)構(gòu)造方法切換公平和非公平

Sync父類(lèi)AbstractQueuedSynchronize(AQS) 此處的鎖具備synchronized功能,即可以阻塞一個(gè)線(xiàn)程。

為了實(shí)現(xiàn)一把具有阻塞或喚醒功能的鎖,需要幾個(gè)核心要素

(1) state變量,標(biāo)記鎖狀態(tài)。至少有兩個(gè)值0/1。對(duì)state的操作,使用CAS保證線(xiàn)程安全

  • AbstractQueuedSynchronizer類(lèi)里有變量private volatile int state 記錄鎖狀態(tài)
  • state=0,沒(méi)有線(xiàn)程持有鎖,exclusiveOwnerThread=null
  • state=1,有一個(gè)線(xiàn)程持有鎖,exclusiveOwnerThread=該線(xiàn)程
  • state > 1,說(shuō)明該線(xiàn)程重入了該鎖,等于幾就重入了幾次

(2) 需要記錄當(dāng)前是哪個(gè)線(xiàn)程持有鎖

  • AbstractOwnableSynchronizer里面有變量private transient Thread exclusiveOwnerThread;記錄鎖持有的線(xiàn)程

(3) 需要底層支持對(duì)一個(gè)線(xiàn)程進(jìn)行阻塞或喚醒操作

  • public native void unpark(Object thread); // 喚醒某一個(gè)線(xiàn)程
  • public native void park(boolean isAbsolute, long time); // 阻塞某一個(gè)線(xiàn)程 實(shí)現(xiàn)一個(gè)線(xiàn)程對(duì)另外一個(gè)線(xiàn)程的精準(zhǔn)喚醒
  • 一般使用LockSupport的工具類(lèi),對(duì)上面兩個(gè)方法進(jìn)行了封裝
  • 當(dāng)前線(xiàn)程中調(diào)用park()就會(huì)被阻塞 另一個(gè)線(xiàn)程調(diào)用unpark(Thread t)傳入被阻塞線(xiàn)程就可喚醒阻塞在park()地方的線(xiàn)程

(4) 需要有一個(gè)隊(duì)列維護(hù)所有阻塞的線(xiàn)程。這個(gè)隊(duì)列也必須是線(xiàn)程安全的無(wú)鎖隊(duì)列,也需要使用CAS對(duì)隊(duì)列進(jìn)行增加或刪除

public abstract class AbstractQueuedSynchronizer {
  // 雙向鏈表
  static final class Node {
  volatile Thread thread;  // 每個(gè)Node對(duì)應(yīng)一個(gè)被阻塞的線(xiàn)程
  volatile Node prev;      // 前一個(gè)
  volatile Node next;      // 后一個(gè)
 }
private transient volatile Node head;   // 頭
private transient volatile Node tail;   // 尾
}

阻塞隊(duì)列是整個(gè)AQS核心中的核心。如下圖所示,head指向雙向鏈表頭部,tail指向雙向鏈表尾部。入隊(duì)就是把新的Node加到tail后面,然后對(duì)tail進(jìn)行CAS操作;

出隊(duì)就是對(duì)head進(jìn)行CAS操作,把head向后移一個(gè)位置

在這里插入圖片描述

初始的時(shí)候,head=tail=NULL;然后,在往隊(duì)列中加入阻塞的線(xiàn)程時(shí),會(huì)新建一個(gè)空的Node,讓head和tail都指向這個(gè)空Node;之后,在后面加入被阻塞的線(xiàn)程對(duì)象。

所以,當(dāng)head=tail的時(shí)候,說(shuō)明隊(duì)列為空。

到此這篇關(guān)于Java中的ReentrantLock實(shí)現(xiàn)原理及代碼演示的文章就介紹到這了,更多相關(guān)ReentrantLock實(shí)現(xiàn)原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Cache整合Redis實(shí)現(xiàn)方法詳解

    Spring Cache整合Redis實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了Spring Cache整合Redis實(shí)現(xiàn)方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Mybatis如何傳入多個(gè)參數(shù)的實(shí)現(xiàn)代碼

    Mybatis如何傳入多個(gè)參數(shù)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Mybatis如何傳入多個(gè)參數(shù)的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • SpringBoot讀取application.yml作為配置的處理

    SpringBoot讀取application.yml作為配置的處理

    SpringBoot支持將配置放在application.yml或application.properties中,自動(dòng)加載并注入到應(yīng)用中,使用@Value或@ConfigurationProperties讀取配置,推薦使用后者處理結(jié)構(gòu)化配置
    2026-04-04
  • Java集合類(lèi)的組織結(jié)構(gòu)和繼承、實(shí)現(xiàn)關(guān)系詳解

    Java集合類(lèi)的組織結(jié)構(gòu)和繼承、實(shí)現(xiàn)關(guān)系詳解

    這篇文章主要介紹了Java集合類(lèi)的組織結(jié)構(gòu)和繼承、實(shí)現(xiàn)關(guān)系,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • IntelliJ IDEA Java項(xiàng)目手動(dòng)添加依賴(lài) jar 包的方法(圖解)

    IntelliJ IDEA Java項(xiàng)目手動(dòng)添加依賴(lài) jar 包的方法(圖解)

    這篇文章主要介紹了IntelliJ IDEA Java項(xiàng)目手動(dòng)添加依賴(lài) jar 包,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • java使用EasyExcel實(shí)現(xiàn)Sheet的復(fù)制與填充

    java使用EasyExcel實(shí)現(xiàn)Sheet的復(fù)制與填充

    EasyExcel是一個(gè)非常有用的工具,它提供了強(qiáng)大的模板填充功能,可以輕松解決各種業(yè)務(wù)需求,本文主要為大家介紹了如何使用EasyExcel實(shí)現(xiàn)模板Sheet復(fù)制與填充,需要的可以參考下
    2023-10-10
  • Java獲取兩個(gè)字符串中最大相同子串的方法

    Java獲取兩個(gè)字符串中最大相同子串的方法

    今天小編就為大家分享一篇Java獲取兩個(gè)字符串中最大相同子串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Java線(xiàn)程通訊的實(shí)現(xiàn)方法總結(jié)

    Java線(xiàn)程通訊的實(shí)現(xiàn)方法總結(jié)

    線(xiàn)程通訊指的是多個(gè)線(xiàn)程之間通過(guò)共享內(nèi)存或消息傳遞等方式來(lái)協(xié)調(diào)和同步它們的執(zhí)行,線(xiàn)程通訊的實(shí)現(xiàn)方式主要有以下兩種:共享內(nèi)存和消息傳遞,本文詳細(xì)介紹了Java線(xiàn)程是如何通訊的,感興趣的同學(xué)可以參考閱讀
    2023-05-05
  • 教你如何編寫(xiě)簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng)

    教你如何編寫(xiě)簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng)

    實(shí)際的爬蟲(chóng)是從一系列的種子鏈接開(kāi)始。種子鏈接是起始節(jié)點(diǎn),種子頁(yè)面的超鏈接指向的頁(yè)面是子節(jié)點(diǎn)(中間節(jié)點(diǎn)),對(duì)于非html文檔,如excel等,不能從中提取超鏈接,看做圖的終端節(jié)點(diǎn)
    2013-10-10
  • idea編譯器工程out目錄修改方法步驟

    idea編譯器工程out目錄修改方法步驟

    多個(gè)工程在一個(gè)文件夾下,有時(shí)會(huì)變?yōu)樗械墓こ讨挥靡粋€(gè)out文件夾,這時(shí)運(yùn)行會(huì)出錯(cuò),所以本文就來(lái)介紹一下out目錄修改,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09

最新評(píng)論

兴宁市| 天镇县| 酒泉市| 准格尔旗| 高邮市| 三门县| 宁海县| 奉化市| 高清| 丹东市| 新民市| 深泽县| 和林格尔县| 平舆县| 新乡县| 青州市| 会同县| 南丹县| 布拖县| 凭祥市| 图们市| 阳高县| 汕头市| 东兰县| 高平市| 东方市| 章丘市| 卓尼县| 绥阳县| 邢台县| 驻马店市| 耿马| 三原县| 大埔县| 边坝县| 抚松县| 舞钢市| 衡水市| 华宁县| 探索| 资阳市|