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

探索Java并發(fā)編程利器:LockSupport,一種高效的線程阻塞與喚醒機制

這篇具有很好參考價值的文章主要介紹了探索Java并發(fā)編程利器:LockSupport,一種高效的線程阻塞與喚醒機制。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

關于作者:CSDN內(nèi)容合伙人、技術專家, 從零開始做日活千萬級APP。
專注于分享各領域原創(chuàng)系列文章 ,擅長java后端、移動開發(fā)、人工智能等,希望大家多多支持。

探索Java并發(fā)編程利器:LockSupport,一種高效的線程阻塞與喚醒機制,java學習之路,java,android,面試,線程,并發(fā)

一、導讀

我們繼續(xù)總結(jié)學習Java基礎知識,溫故知新。

二、概覽

LockSupport 是 Java SE 9 及以上版本中引入的一個線程同步工具類,用于支持同步方法,提供了多種同步機制.

LockSupport 所有的方法都是靜態(tài)方法,可以讓線程在任意位置阻塞,阻塞之后也有對應的喚醒方法。
LockSupport 底層調(diào)用的是Unsafe中的native代碼。

java.util.concurrent并發(fā)包下很多并發(fā)類的底層加鎖都是基于LockSupport,如ReentrantLock、CountDownLatch、ParkableLazyDeque 等。

三、用法

LockSupport 類中最常用的方法是 Park() 和 Unpark() 方法,分別用于阻塞和喚醒線程。


       Thread a = new Thread(() -> {

           System.out.println("start " + Thread.currentThread().getName());
           int resule = 0;
           for(int i = 0; i < 10; i ++) {
               resule += i;
           }
           // 阻塞線程
           LockSupport.park();
           System.out.println(resule);

       }, "a");

       a.start();
       try {
//            TimeUnit.MILLISECONDS.sleep(1000);
       } catch (Exception e) {
       }
       
       // 釋放,這里不調(diào)用的話,上面將一直鎖定
       LockSupport.unpark(a);

四、原理

park和unpark都是直接調(diào)用了Unsafe的方法,
我們這么理解:這兩個方法的原理是基于一個計數(shù)器,計數(shù)器的值決定了線程的阻塞等待狀態(tài)。當計數(shù)器的值減為 0 時,表示線程可以被喚醒,執(zhí)行相應的操作。

此外,LockSupport 還提供了一些同步方法,如 Lock 和 Unlock() 方法,用于獲取和釋放鎖。Lock 方法用于獲取鎖,Unlock() 方法用于釋放鎖。與 synchronized 關鍵字不同,Lock 和 Unlock() 方法不需要同時進行,可以在任意一個方法中獲取鎖,并且可以在任意一個方法中釋放鎖,因此更加靈活和方便。


    調(diào)用park后,此時線程處于waiting的狀態(tài)
    
    public static void park() {
        UNSAFE.park(false, 0L);
    }
    
    public static void park(Object blocker) {
        // 獲取當前線程
        Thread t = Thread.currentThread();
        
        // 設置Blocker
        setBlocker(t, blocker);
        
        // 此后,當前線程就已經(jīng)阻塞了,后面的函數(shù)無法運行,直至unpark函數(shù)被調(diào)用
        UNSAFE.park(false, 0L);
        
        //unpark函數(shù)被調(diào)用后,繼續(xù)執(zhí)行,如果沒有第二個setBlocker,那么之后沒有調(diào)用park(Object blocker),
        //而直接調(diào)用getBlocker函數(shù),得到的還是前一個park(Object blocker)設置的blocker,顯然是不符合邏輯的
        setBlocker(t, null);
    }
    
    public static void unpark(Thread thread) {
        if (thread != null)
           UNSAFE.unpark(thread);
    }

Unsafe.java


    public native void unpark(Object var1);

    public native void park(boolean var1, long var2);

五、線程等待和喚醒的方法

5.1 LockSupport.park()

    // Hotspot implementation via intrinsics API
    private static final sun.misc.Unsafe UNSAFE;
    
    static {
        try {
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            
        } catch (Exception ex) { throw new Error(ex); }
    }

Thread.sleep()和LockSupport.park()的區(qū)別

Thread.sleep()和LockSupport.park() 都是阻塞當前線程的執(zhí)行,
都 不會 釋放 當前線程占有的鎖資源;

  • Thread.sleep()沒法從外部喚醒,只能自己醒過來;本身就是一個native方法;
  • LockSupport.park()方法可以被另一個線程調(diào)用LockSupport.unpark()方法喚醒;* 底層是調(diào)用的Unsafe的native方法;

Thread.sleep()方法需要捕獲中斷異常。
LockSupport.park()不需要捕獲中斷異常。

5.2 Object中的wait()、notify、notifyAll

Object類中的wait、notify、notifyAll用于線程等待和喚醒的方法,都必須在sychronized內(nèi)部執(zhí)行

Object.wait()原理

在 Object.wait() 方法中,首先使用 synchronized 關鍵字鎖定當前對象,然后調(diào)用 Object.wait() 方法等待另一個線程執(zhí)行完畢并返回一個 Future 對象。在等待過程中,當前線程會一直阻塞,直到另一個線程執(zhí)行完畢并返回一個 Future 對象。當?shù)却€程執(zhí)行完畢后,F(xiàn)uture 對象的 get() 方法將返回等待線程的結(jié)果。因此,在使用 Object.wait() 方法時,需要確保等待線程已經(jīng)執(zhí)行完畢,否則可能會導致死鎖等問題。

5.3 Condition的await()方法

Java中的Condition是java.util.concurrent.locks包下的一個接口,它主要用于在多線程環(huán)境中控制線程的等待和喚醒。

線程需要獲得并持有鎖,必須在鎖塊(synchronized或lock中)
必須要先等待后喚醒,線程才能夠被喚醒。

5.4 Thread.sleep()和Object.wait()的區(qū)別

Thread.sleep()不會釋放鎖資源,到時間了會自動喚醒,然后繼續(xù)執(zhí)行;
Object.wait()會釋放鎖資源。需要另一個線程使用Object.notify()喚醒

5.5 Object.wait()和LockSupport.park()的區(qū)別

二者都會阻塞當前線程的運行。

  • Object.wait()方法需要在synchronized塊中執(zhí)行;

  • LockSupport.park()可以在任意地方執(zhí)行;

  • Object.wait()方法需要捕獲中斷異常。

  • LockSupport.park()不需要捕獲中斷異常。

  • Object.wait()不帶超時的,需要另一個線程執(zhí)行notify()來喚醒,但不一定繼續(xù)執(zhí)行后續(xù)內(nèi)容;

  • LockSupport.park()不帶超時的,需要另一個線程執(zhí)行unpark()來喚醒,一定會繼續(xù)執(zhí)行后續(xù)內(nèi)容;

5.6 Object.wait()和Condition.await()的區(qū)別

Object.wait()和Condition.await()的原理是基本一致的,不同的是Condition.await()底層是調(diào)用LockSupport.park()來實現(xiàn)阻塞當前線程的。

5.7 java中,notify/wait等方法為什么要在同步代碼塊中執(zhí)行

同步代碼塊通常由 synchronized 關鍵字修飾
在Java中,notify() 和 wait() 方法通常用于實現(xiàn)線程之間的通信和同步。這些方法通常在同步代碼塊中執(zhí)行,以確保線程安全和原子性。
在同步代碼塊中執(zhí)行 notify() 和 wait() 方法可以確保線程安全和原子性,因為它們可以保證在同一時刻只有一個線程可以執(zhí)行這些方法。如果在非同步代碼塊中執(zhí)行這些方法,則可能會導致競爭條件和死鎖等問題。

5.8 如果在wait()之前執(zhí)行了notify()會怎樣?

如果當前的線程不是此對象鎖的所有者,卻調(diào)用該對象的notify()或wait()方法時拋出IllegalMonitorStateException異常;
如果當前線程是此對象鎖的所有者,wait()將一直阻塞,因為后續(xù)將沒有其它notify()喚醒它。

5.8 如果在park()之前執(zhí)行了unpark()會怎樣?

線程不會被阻塞,直接跳過park(),繼續(xù)執(zhí)行后續(xù)內(nèi)容,大家可以自己嘗試下


        Thread a = new Thread(() -> {

            System.out.println("start " + Thread.currentThread().getName());
            int resule = 0;
            for(int i = 0; i < 10; i ++) {
                resule += i;
            }
            LockSupport.park();
            System.out.println(resule);

        }, "a");

        try {
//            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (Exception e) {
        }
        LockSupport.unpark(a);
        a.start();
        LockSupport.unpark(a);

六、 推薦閱讀

Java 專欄

SQL 專欄

數(shù)據(jù)結(jié)構(gòu)與算法

Android學習專欄文章來源地址http://www.zghlxwxcb.cn/news/detail-602135.html

到了這里,關于探索Java并發(fā)編程利器:LockSupport,一種高效的線程阻塞與喚醒機制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領支付寶紅包贊助服務器費用

相關文章

  • Java并發(fā)編程之線程池詳解

    Java并發(fā)編程之線程池詳解

    目錄 ??今日良言:不悲傷 不彷徨 有風聽風 有雨看雨 ??一、簡介 ??二、相關代碼 ??1.線程池代碼 ??2.自定義實現(xiàn)線程池 ??三、ThreadPoolExecutor類 首先來介紹一下什么是線程池,線程池是一種利用池化技術思想來實現(xiàn)的線程管理技術,主要是為了復用線程、便利地管理線程

    2024年02月12日
    瀏覽(23)
  • Java并發(fā)編程面試題——線程池

    Java并發(fā)編程面試題——線程池

    參考文章: 《Java 并發(fā)編程的藝術》 7000 字 + 24 張圖帶你徹底弄懂線程池 (1) 線程池 (ThreadPool) 是一種用于 管理和復用線程的機制 ,它是在程序啟動時就預先創(chuàng)建一定數(shù)量的線程,將這些線程放入一個池中,并對它們進行有效的管理和復用,從而在需要執(zhí)行任務時,可以從

    2024年02月07日
    瀏覽(43)
  • 【Java 并發(fā)編程】一文讀懂線程、協(xié)程、守護線程

    【Java 并發(fā)編程】一文讀懂線程、協(xié)程、守護線程

    在 Java 線程的生命周期一文中提到了 就緒狀態(tài)的線程在獲得 CPU 時間片后變?yōu)檫\行中狀態(tài) ,否則就會在 可運行狀態(tài) 或者 阻塞狀態(tài) ,那么系統(tǒng)是如何分配線程時間片以及實現(xiàn)線程的調(diào)度的呢?下面我們就來講講線程的調(diào)度策略。 線程調(diào)度是指系統(tǒng)為線程分配 CPU 執(zhí)行時間片

    2023年04月08日
    瀏覽(24)
  • 【Java并發(fā)編程】變量的線程安全分析

    【Java并發(fā)編程】變量的線程安全分析

    1.成員變量和靜態(tài)變量是否線程安全? 如果他們沒有共享,則線程安全 如果被共享: 只有讀操作,則線程安全 有寫操作,則這段代碼是臨界區(qū),需要考慮線程安全 2.局部變量是否線程安全 局部變量是線程安全的 當局部變量引用的對象則未必 如果給i對象沒有逃離方法的作用

    2024年02月08日
    瀏覽(90)
  • Java面試_并發(fā)編程_線程基礎

    Java面試_并發(fā)編程_線程基礎

    進程是正在運行程序的實例, 進程中包含了線程, 每個線程執(zhí)行不同的任務 不同的進程使用不同的內(nèi)存空間, 在當前進程下的所有線程可以共享內(nèi)存空間 線程更輕量, 線程上下文切換成本一般上要比進程上下文切換低(上下文切換指的是從一個線程切換到另一個線程) 并發(fā)是單個

    2024年02月07日
    瀏覽(30)
  • 【Java 并發(fā)編程】Java 線程本地變量 ThreadLocal 詳解

    【Java 并發(fā)編程】Java 線程本地變量 ThreadLocal 詳解

    先一起看一下 ThreadLocal 類的官方解釋: 用大白話翻譯過來,大體的意思是: ThreadLoal 提供給了 線程局部變量 。同一個 ThreadLocal 所包含的對象,在不同的 Thread 中有不同的副本。這里有幾點需要注意: 因為每個 Thread 內(nèi)有自己的實例副本,且 該副本只能由當前 Thread 使用 。

    2024年02月04日
    瀏覽(31)
  • 【Java并發(fā)編程】線程中斷機制(輔以常見案例)

    本文由淺入深介紹了中斷機制、中斷的常見案例和使用場景。 因為一些原因需要取消原本正在執(zhí)行的線程。我們舉幾個栗子: 假設踢足球點球時,A隊前4輪中了4個球,B隊前4輪只中了2個球,此時勝負已分,第5輪這個點球就不用踢了,此時需要停止A隊的線程和B隊的線程(共

    2024年02月13日
    瀏覽(30)
  • java并發(fā)編程:多線程基礎知識介紹

    最初的計算機只能接受一些特定的指令,用戶每輸入一個指令,計算機就做出一個操作。當用戶在思考或者輸入時,計算機就在等待。這樣效率非常低下,在很多時候,計算機都處在等待狀態(tài)。 后來有了 批處理操作系統(tǒng) ,把一系列需要操作的指令寫下來,形成一個清單,一次

    2024年02月07日
    瀏覽(21)
  • Java并發(fā)編程第6講——線程池(萬字詳解)

    Java并發(fā)編程第6講——線程池(萬字詳解)

    Java中的線程池是運用場景最多的并發(fā)框架,幾乎所有需要異步或并發(fā)執(zhí)行任務的程序都可以使用線程池,本篇文章就詳細介紹一下。 定義:線程池是一種用于管理和重用線程的技術(池化技術),它主要用于提高多線程應用程序的性能和效率。 ps:線程池、連接池、內(nèi)存池

    2024年02月11日
    瀏覽(27)
  • Java并發(fā)編程學習18-線程池的使用(下)

    上篇介紹了 ThreadPoolExecutor 配置和擴展相關的信息,本篇開始將介紹遞歸算法的并行化。 還記得我們在《Java并發(fā)編程學習11-任務執(zhí)行演示》中,對頁面繪制程序進行一系列改進,這些改進大大地提供了頁面繪制的并行性。 我們簡單回顧下相關的改進過程: 第一次新增時,頁

    2024年02月12日
    瀏覽(24)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領取紅包

二維碼2

領紅包