欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java四個線程常用函數(shù)超全使用詳解

 更新時間:2022年03月23日 09:05:12   作者:碼農(nóng)研究僧  
這篇文章主要為大家介紹了線程中常用的四個函數(shù):wait()、join()、sleep() 和 yield(),以及這四個函數(shù)的使用方法和相互之間的區(qū)別,需要的可以參考一下

前言

之前沒怎么關注到這兩個的區(qū)別以及源碼探討

后面被某個公司面試問到了,開始查漏補缺

1. wait()

使當前線程等待,直到它被喚醒,通常是通過被通知或被中斷,或者直到經(jīng)過一定的實時時間。

本身屬于一個Object 類,查看源代碼也可知:public class Object {

查看其源碼可知,一共有三個重載的方法,詳情源代碼如下:

//第一個重載函數(shù)
public final void wait() throws InterruptedException {
        wait(0L);
    }
    
//第二個重載函數(shù)
public final native void wait(long timeoutMillis) throws InterruptedException;


//第三個重載函數(shù)
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }

具體實戰(zhàn)調用代碼如下:

如果執(zhí)行到了wait函數(shù),在這4秒內,會釋放鎖,并且暫停線程。如果這四秒內配合notify()可以喚醒并且得到鎖,如果沒有喚醒,等待其他來競爭。4秒結束后,會默認自動釋放鎖

當前線程在 Thread.wait()等待過程中,如果Thread結束了,是可以自動喚醒的而且自動釋放鎖

@Override
public void run() {
       synchronized (a) {
           a.wait(4000);      
       }
}

2. join()

join是Thread類的方法

查看其源碼,具體源碼如下,三個重載的方法

//第一個重載函數(shù)
public final synchronized void join(final long millis)
    throws InterruptedException {
        if (millis > 0) {
            if (isAlive()) {
                final long startTime = System.nanoTime();
                long delay = millis;
                do {
                    wait(delay);
                } while (isAlive() && (delay = millis -
                        TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);
            }
        } else if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            throw new IllegalArgumentException("timeout value is negative");
        }
    }


//第二個重載函數(shù)
/*等待該線程死亡的時間最多為毫秒加納秒。 如果兩個參數(shù)都為0,則意味著永遠等待。  
這個實現(xiàn)使用了This的循環(huán)。 等待電話以this.isAlive為條件。 當一個線程終止this。 
調用notifyAll方法。 建議應用程序不要使用wait、notify或notifyAll on Thread實例。  */
public final synchronized void join(long millis, int nanos)
throws InterruptedException {

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }

    if (nanos > 0 && millis < Long.MAX_VALUE) {
        millis++;
    }

    join(millis);
}


//第三個重載函數(shù)
/*等待線程死亡。  
此方法的調用與調用的行為完全相同  

InterruptedException—如果任何線程中斷了當前線程。 當拋出此異常時,當前線程的中斷狀態(tài)將被清除。  */
public final void join() throws InterruptedException {
     join(0);
 }

主要的時間參數(shù)邏輯如下:

  • 小于0,拋出異常
  • 等于0,join(A),判斷A是否存在,存在才執(zhí)行操作。該線程執(zhí)行wait(0)等待,等待A線程執(zhí)行完后才可結束
  • 大于0,同上,只不過執(zhí)行的是wait(long millis),等待時間結束后才可繼續(xù)執(zhí)行操作

3. sleep()

對比上一個wait函數(shù)

  • sleep(long mills):讓出CPU資源,但是不會釋放鎖資源。
  • wait():讓出CPU資源和鎖資源。

查看sleep函數(shù)的源碼,一共有兩個重載函數(shù)

都是Thread類的函數(shù)

/*根據(jù)系統(tǒng)計時器和調度器的精度和準確性,
使當前執(zhí)行的線程在指定的毫秒數(shù)內處于睡眠狀態(tài)(暫時停止執(zhí)行)。 
線程不會失去任何監(jiān)視器的所有權。*/
public static native void sleep(long millis) throws InterruptedException;



/*導致當前執(zhí)行的線程在指定的毫秒數(shù)加上指定的納秒數(shù)
(取決于系統(tǒng)計時器和調度器的精度和準確性)內休眠(暫時停止執(zhí)行)。 
線程不會失去任何監(jiān)視器的所有權。  */
public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && millis < Long.MAX_VALUE) {
            millis++;
        }

        sleep(millis);
    }

4. yield()

查看yield()函數(shù)的源碼,一個重載函數(shù)

都是Thread類的函數(shù)

向調度器暗示當前線程愿意放棄當前對處理器的使用。 調度器可以忽略這個提示。

Yield是一種啟發(fā)式嘗試,旨在改善線程之間的相對進程,否則會過度使用CPU。 它的使用應該與詳細的分析和基準測試相結合,以確保它實際上具有預期的效果。

使用這種方法很少是合適的。 它可能用于調試或測試目的,在這些目的中,它可能有助于由于競爭條件而重新生成錯誤。 在設計并發(fā)控制構造(如java.util.concurrent.locks包中的構造)時,它可能也很有用。

public static native void yield();

總的來說,yield函數(shù)的功能主要是:

讓出CPU調度,暫停線程,但不能由用戶指定時間

只能讓同優(yōu)先級有執(zhí)行機會

5. 總結

wait 暫停該線程,讓出cpu,釋放鎖。(Object類)

join暫停該線程,執(zhí)行該線程之后才能回到自身的線程運行。(Thread類)

sleep 暫停該線程,讓出cpu,不釋放鎖。(Thread類)

yield 暫停該線程,但是不能由用戶制定,只能讓同優(yōu)先級有執(zhí)行機會。(Thread類)

5.1 wait和join的區(qū)別

看完以上的源碼以及邏輯代碼,再講講兩者的異同

總的來說

  • wait函數(shù):讓當前線程進入等待狀態(tài),wait()會與notify()和notifyAll()方法一起使用。notify為喚醒函數(shù)
  • join函數(shù):等待這個線程結束才能執(zhí)行自已的線程。它的主要起同步作用,使線程之間的執(zhí)行從“并行”變成“串行”。線程A中調用了線程B的join()方法時,線程

執(zhí)行過程發(fā)生改變:線程A,必須等待線程B執(zhí)行完畢后,才可以繼續(xù)執(zhí)行下去

共同點:

  • 暫停當前的線程
  • 都可以通過中斷喚醒

不同點在于:

區(qū)別waitjoin
Object類Thread類
目的線程間通信排序,讓其串行通過
同步必須要synchronized可以不用synchronized

5.2 wait和sleep的區(qū)別

wait():讓出CPU資源和鎖資源。

sleep(long mills):讓出CPU資源,但是不會釋放鎖資源。

看區(qū)別,主要是看CPU的運行機制:

它們的區(qū)別主要考慮兩點:1.cpu是否繼續(xù)執(zhí)行、2.鎖是否釋放掉。

歸根到底:

wait,notify,notifyall 都是Object對象的方法,是一起使用的,用于鎖機制,所以會釋放鎖

而sleep是Thread類,跟鎖沒關系,不會釋放鎖

但是兩者都會讓出cpu資源

以上就是Java四個線程常用函數(shù)超全使用詳解的詳細內容,更多關于Java線程函數(shù)的資料請關注腳本之家其它相關文章!

相關文章

  • SpringBoot整合Mail發(fā)送郵件功能

    SpringBoot整合Mail發(fā)送郵件功能

    我們在網(wǎng)站上注冊賬號的時候一般需要獲取驗證碼,而這個驗證碼一般發(fā)送在你的手機號上還有的是發(fā)送在你的郵箱中,注冊,賬號密碼…都需要用到驗證,今天就演示一下如何用SpringBoot整合Mail發(fā)送郵箱
    2021-11-11
  • Spring中@Import的各種用法以及ImportAware接口詳解

    Spring中@Import的各種用法以及ImportAware接口詳解

    這篇文章主要介紹了Spring中@Import的各種用法以及ImportAware接口詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • Spring AOP定義Before增加實戰(zhàn)案例詳解

    Spring AOP定義Before增加實戰(zhàn)案例詳解

    這篇文章主要介紹了Spring AOP定義Before增加,結合實例形式詳細分析了Spring面向切面AOP定義Before增加相關定義與使用技巧,需要的朋友可以參考下
    2020-01-01
  • Java Hashtable機制深入了解

    Java Hashtable機制深入了解

    HashTable是jdk 1.0中引入的產(chǎn)物,基本上現(xiàn)在很少使用了,但是會在面試中經(jīng)常被問到。本文就來帶大家一起深入了解一下Hashtable,需要的可以參考一下
    2022-09-09
  • Java 如何使用Feign發(fā)送HTTP請求

    Java 如何使用Feign發(fā)送HTTP請求

    這篇文章主要介紹了Java 如何使用Feign發(fā)送HTTP請求,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下
    2020-11-11
  • SpringBoot 返回Html界面的操作代碼

    SpringBoot 返回Html界面的操作代碼

    這篇文章主要介紹了SpringBoot 返回Html界面的相關資料,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • SpringBoot自定義全局異常處理器的問題總結

    SpringBoot自定義全局異常處理器的問題總結

    Springboot框架提供兩個注解幫助我們十分方便實現(xiàn)全局異常處理器以及自定義異常,處理器會優(yōu)先處理更具體的異常類型,如果沒有找到匹配的處理器,那么它會尋找處理更一般異常類型的處理器,本文介紹SpringBoot自定義全局異常處理器的問題,一起看看吧
    2024-01-01
  • 使用IntelliJ IDEA調式Stream流的方法步驟

    使用IntelliJ IDEA調式Stream流的方法步驟

    本文主要介紹了使用IntelliJ IDEA調式Stream流的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Java集合中的LinkedHashSet源碼解讀

    Java集合中的LinkedHashSet源碼解讀

    這篇文章主要介紹了Java集合中的LinkedHashSet源碼解讀,在LinkedHashMap中,雙向鏈表的遍歷順序通過構造方法指定,如果沒有指定,則使用默認順序為插入順序,即accessOrder=false,需要的朋友可以參考下
    2023-12-12
  • idea遠程Debug部署在服務器上的服務

    idea遠程Debug部署在服務器上的服務

    在開發(fā)的時候我們通常在本地代碼上debug程序,但是服務部署到了開發(fā)環(huán)境服務器上,如何遠程調試,本文主要介紹了idea遠程Debug部署在服務器上的服務,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12

最新評論