多線程:join方法原理解析!

1.join()解釋:

自我理解:

Waits for this thread to die.(等待該線程{xxx.join()的xxx線程}執行結束後,當前線程再開始執行)換句話說就是誰.join()就等誰執行。

網上解釋:join()是Thread類的一個方法,根據jdk文檔的定義,join()方法的作用,是等待這個線程結束,即當前線程等待另一個調用join()方法的線程執行結束後再往下執行。通常用於在main主線程內,等待其它調用join()方法的線程執行結束再繼續執行main主線程。(來源:https://www.jianshu.com/p/5d88b122a050

2.應用實例:

需求:

從幾臺服務器上採集數據,並將它們的採集的結果存入數據庫

(1).不使用join()

package com.springboot.thread;

/*
* join方法:join()是Thread類的一個方法,根據jdk文檔的定義,
* join()方法的作用,是等待這個線程結束,即當前線程等待另一個
* 調用join()方法的線程執行結束後再往下執行。
* 通常用於在main主線程內,等待其它調用join()方法的線程執行結束再繼續執行main主線程。
* */
public class ThreadJoinDemo {
    /*需求模擬:從幾臺服務器上採集數據,並將它們的採集的結果存入數據庫*/
    public static void main(String[] args) {
        System.out.println("開始收集");
        Thread thread1 = new Thread(new ComputerRunable("M1",1000l));
        Thread thread2 = new Thread(new ComputerRunable("M2",2000L));
        Thread thread3 = new Thread(new ComputerRunable("M3",3000L));
        thread1.start();
        thread2.start();
        thread3.start();
        System.out.println("收集結束");
    }
}

class ComputerRunable implements Runnable{
    private String computerName;
    private Long spentTime;

    public ComputerRunable(String computerName,Long spentTime) {
        this.computerName = computerName;
        this.spentTime = spentTime;
    }


    @Override
    public void run() {
        /*採集數據*/
        try {
            Thread.sleep(spentTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(computerName+"數據收集完畢!");
    }
}

運行結果:

開始收集
收集結束
M1數據收集完畢!
M2數據收集完畢!
M3數據收集完畢!

 可以看出:我們還沒有開始收集,主線程就已經結束了。

(2).使用join()

package com.springboot.thread;

/*
* join方法:join()是Thread類的一個方法,根據jdk文檔的定義,
* join()方法的作用,是等待這個線程結束,即當前線程等待另一個
* 調用join()方法的線程執行結束後再往下執行。
* 通常用於在main主線程內,等待其它調用join()方法的線程執行結束再繼續執行main主線程。
* */
public class ThreadJoinDemo {
    /*需求模擬:從幾臺服務器上採集數據,並將它們的採集的結果存入數據庫*/
    public static void main(String[] args) throws InterruptedException {
        System.out.println("開始收集");
        Thread thread1 = new Thread(new ComputerRunable("M1",1000l));
        Thread thread2 = new Thread(new ComputerRunable("M2",2000L));
        Thread thread3 = new Thread(new ComputerRunable("M3",3000L));
        thread1.start();
        thread2.start();
        thread3.start();
        thread1.join();
        thread2.join();
        thread3.join();
        System.out.println("收集結束");
    }
}

class ComputerRunable implements Runnable{
    private String computerName;
    private Long spentTime;

    public ComputerRunable(String computerName,Long spentTime) {
        this.computerName = computerName;
        this.spentTime = spentTime;
    }


    @Override
    public void run() {
        /*採集數據*/
        try {
            Thread.sleep(spentTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(computerName+"數據收集完畢!");
    }
}

運行結果:

開始收集
M1數據收集完畢!
M2數據收集完畢!
M3數據收集完畢!
收集結束

從運行結果來看:符合我們的預期。

3.join的實現原理:

 public final synchronized void join(long millis) throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (millis == 0) { //判斷是否攜帶阻塞的超時時間,等於0表示沒有設置超時時間
            while (isAlive()) {//isAlive獲取線程狀態,無線等待直到previousThread線程結束
                wait(0); //調用Object中的wait方法實現線程的阻塞
            }
        } else { //阻塞直到超時
            while (isAlive()) { 
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

解析:從join方法的源碼來看,join方法的本質調用的是Object中的wait方法實現線程的阻塞,wait方法的實現原理我們在後續的文章再說詳細闡述。但是我們需要知道的是,調用wait方法必須要獲取鎖,所以join方法是被synchronized修飾的,synchronized修飾在方法層面相當於synchronized(this),this就是previousThread本身的實例。(來源:https://www.jianshu.com/p/fc51be7e5bc0

4.參考資料:

(1).https://www.jianshu.com/p/5d88b122a050

(2).https://www.jianshu.com/p/fc51be7e5bc0【重點推薦】

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章