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

Java中的Thread.join()詳解

 更新時間:2023年09月14日 10:36:13   作者:Chen洋  
這篇文章主要介紹了Thread.join()詳解?,join是Thread類的一個方法,啟動線程后直接調用,本文通過實例代碼介紹了join方法的作用及用法詳解,需要的朋友可以參考下

一、使用方式。

join是Thread類的一個方法,啟動線程后直接調用,例如:

Thread t = new AThread(); t.start(); t.join();

二、為什么要用join()方法

在很多情況下,主線程生成并起動了子線程,如果子線程里要進行大量的耗時的運算,主線程往往將于子線程之前結束,但是如果主線程處理完其他的事務后,需要用到子線程的處理結果,也就是主線程需要等待子線程執(zhí)行完成之后再結束,這個時候就要用到join()方法了。

三、join方法的作用

在JDk的API里對于join()方法是:

即join()的作用是:“等待該線程終止”,這里需要理解的就是該線程是指的主線程等待子線程的終止。也就是在子線程調用了join()方法后面的代碼,只有等到子線程結束了才能執(zhí)行。

四、用實例來理解

寫一個簡單的例子來看一下join()的用法:

1.AThread 類

  • BThread類

  • TestDemo 類

class BThread extends Thread {
    public BThread() {
        super("[BThread] Thread");
    };
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " start.");
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println(threadName + " loop at " + i);
                Thread.sleep(1000);
            }
            System.out.println(threadName + " end.");
        } catch (Exception e) {
            System.out.println("Exception from " + threadName + ".run");
        }
    }
}
class AThread extends Thread {
    BThread bt;
    public AThread(BThread bt) {
        super("[AThread] Thread");
        this.bt = bt;
    }
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " start.");
        try {
            bt.join();
            System.out.println(threadName + " end.");
        } catch (Exception e) {
            System.out.println("Exception from " + threadName + ".run");
        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " start.");
        BThread bt = new BThread();
        AThread at = new AThread(bt);
        try {
            bt.start();
            Thread.sleep(2000);
            at.start();
            at.join();
        } catch (Exception e) {
            System.out.println("Exception from main");
        }
        System.out.println(threadName + " end!");
    }
}

打印結果:

main start.    //主線程起動,因為調用了at.join(),要等到at結束了,此線程才能向下執(zhí)行。 
[BThread] Thread start. 
[BThread] Thread loop at 0 
[BThread] Thread loop at 1 
[AThread] Thread start.    //線程at啟動,因為調用bt.join(),等到bt結束了才向下執(zhí)行。 
[BThread] Thread loop at 2 
[BThread] Thread loop at 3 
[BThread] Thread loop at 4 
[BThread] Thread end. 
[AThread] Thread end.    // 線程AThread在bt.join();阻塞處起動,向下繼續(xù)執(zhí)行的結果 
main end!      //線程AThread結束,此線程在at.join();阻塞處起動,向下繼續(xù)執(zhí)行的結果。

修改一下代碼:

public class TestDemo {
    public static void main(String[] args) {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " start.");
        BThread bt = new BThread();
        AThread at = new AThread(bt);
        try {
            bt.start();
            Thread.sleep(2000);
            at.start();
            //at.join(); //在此處注釋掉對join()的調用
        } catch (Exception e) {
            System.out.println("Exception from main");
        }
        System.out.println(threadName + " end!");
    }
}

打印結果:

main start.    // 主線程起動,因為Thread.sleep(2000),主線程沒有馬上結束;

[BThread] Thread start.    //線程BThread起動
[BThread] Thread loop at 0
[BThread] Thread loop at 1
main end!   // 在sleep兩秒后主線程結束,AThread執(zhí)行的bt.join();并不會影響到主線程。
[AThread] Thread start.    //線程at起動,因為調用了bt.join(),等到bt結束了,此線程才向下執(zhí)行。
[BThread] Thread loop at 2
[BThread] Thread loop at 3
[BThread] Thread loop at 4
[BThread] Thread end.    //線程BThread結束了
[AThread] Thread end.    // 線程AThread在bt.join();阻塞處起動,向下繼續(xù)執(zhí)行的結果

五、從源碼看join()方法

在AThread的run方法里,執(zhí)行了bt.join();,進入看一下它的JDK源碼:

public final void join() throws InterruptedException {
    join(0L);
}

然后進入join(0L)方法:

public final synchronized void join(long l)
    throws InterruptedException
{
    long l1 = System.currentTimeMillis();
    long l2 = 0L;
    if(l < 0L)
        throw new IllegalArgumentException("timeout value is negative");
    if(l == 0L)
        for(; isAlive(); wait(0L));
    else
        do
        {
            if(!isAlive())
                break;
            long l3 = l - l2;
            if(l3 <= 0L)
                break;
            wait(l3);
            l2 = System.currentTimeMillis() - l1;
        } while(true);
}

單純從代碼上看: * 如果線程被生成了,但還未被起動,isAlive()將返回false,調用它的join()方法是沒有作用的。將直接繼續(xù)向下執(zhí)行。

         * 在AThread類中的run方法中,bt.join()是判斷bt的active狀態(tài),如果bt的isActive()方法返回false,在bt.join(),這一點就不用阻塞了,可以繼續(xù)向下進行了。

從源碼里看,wait方法中有參數(shù),也就是不用喚醒誰,只是不再執(zhí)行wait,向下繼續(xù)執(zhí)行而已。

        * 在join()方法中,對于isAlive()和wait()方法的作用對象是個比較讓人困惑的問題:

    isAlive()方法的簽名是:public final native boolean isAlive(),也就是說isAlive()是判斷當前線程的狀態(tài),也就是bt的狀態(tài)。

wait()方法在jdk文檔中的解釋如下:

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

The current thread must own this object's monitor.The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

在這里,當前線程指的是at。

到此這篇關于Thread.join()詳解 的文章就介紹到這了,更多相關Thread.join()詳解 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring+SpringMVC+Hibernate項目環(huán)境搭建的步驟(圖文)

    Spring+SpringMVC+Hibernate項目環(huán)境搭建的步驟(圖文)

    這篇文章主要介紹了Spring+SpringMVC+Hibernate項目環(huán)境搭建的步驟(圖文),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • 使用Kubernetes和Docker部署Java微服務詳細代碼

    使用Kubernetes和Docker部署Java微服務詳細代碼

    Java微服務項目是一種基于Java技術棧的分布式系統(tǒng)開發(fā)方式,下面這篇文章主要給大家介紹了關于使用Kubernetes和Docker部署Java微服務的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-07-07
  • spring cloud整合ribbon問題及解決方案

    spring cloud整合ribbon問題及解決方案

    很多小伙伴在整合ribbon都出了相同的問題,今天特地為大家整理了該問題的解決方案,文中有非常詳細的圖文解說,對出現(xiàn)同樣問題的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • JAVA找不到符號的三種解決方案

    JAVA找不到符號的三種解決方案

    這篇文章主要給大家介紹了關于JAVA找不到符號的三種解決方案, 找不到符號錯誤主要發(fā)生在我們試圖引用一個未在我們正在編譯的程序中聲明的變量時,這意味著編譯器不知道我們所引用的Java變量,需要的朋友可以參考下
    2024-03-03
  • JavaSwing后臺播放音樂mp3

    JavaSwing后臺播放音樂mp3

    這篇文章主要為大家詳細介紹了JavaSwing后臺播放音樂mp3,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Spring MVC映射HTTP請求到Controller的處理方法

    Spring MVC映射HTTP請求到Controller的處理方法

    我們來詳細分析一下如何在 Spring MVC 中將 HTTP 請求映射到 Controller 的處理方法(Handler Methods)上,以及 @RequestMapping 注解的使用方法,需要的朋友可以參考下
    2025-05-05
  • Java案例使用集合方法實現(xiàn)統(tǒng)計任意字符串中字符出現(xiàn)的次數(shù)

    Java案例使用集合方法實現(xiàn)統(tǒng)計任意字符串中字符出現(xiàn)的次數(shù)

    這篇文章主要介紹了Java案例使用集合方法實現(xiàn)統(tǒng)計任意字符串中字符出現(xiàn)的次數(shù),下面我們將用兩種方法實現(xiàn),需要的小伙伴可以參考一下文章具體內容
    2022-04-04
  • Struts2 $,#,%詳解及實例代碼

    Struts2 $,#,%詳解及實例代碼

    這篇文章主要介紹了Struts2 $,#,%詳解及實例代碼的相關資料,需要的朋友可以參考下
    2016-12-12
  • 解決Mybatis的@Param()注解導致分頁失效的問題

    解決Mybatis的@Param()注解導致分頁失效的問題

    這篇文章主要介紹了解決Mybatis的@Param()注解導致分頁失效的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Spring Boot 注解方式自定義Endpoint詳解

    Spring Boot 注解方式自定義Endpoint詳解

    這篇文章主要介紹了Spring Boot注解方式自定義Endpoint詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

闵行区| 平原县| 繁峙县| 黄浦区| 江都市| 孟连| 烟台市| 宕昌县| 永州市| 元朗区| 富裕县| 隆昌县| 孟村| 印江| 钟祥市| 海原县| 仙游县| 奇台县| 南丹县| 大英县| 嘉禾县| 石嘴山市| 化州市| 吉林省| 商都县| 航空| 灵山县| 若尔盖县| 京山县| 宁国市| 阿瓦提县| 北京市| 麻栗坡县| 南城县| 富宁县| 全椒县| 江川县| 屏东县| 望江县| 泸西县| 阿克陶县|