1. 程式人生 > >java多執行緒之守護執行緒Daemon()和Join()介紹

java多執行緒之守護執行緒Daemon()和Join()介紹

最近看了些多執行緒相關的同樣的避免忘了:

我們先模擬一個需求,在http請求的時候我們都會發心跳包,就會一遍又一遍的去檢查心跳是否存在,但是當這個請求不用的時候我們採取什麼方式來把它關閉掉呢?

因為Stop的方法我們已經被java淘汰掉了.這時候我們可以拿守護執行緒來做著件事:

public static void main(String[] args) {

        Thread t = new Thread(() -> { //啟動一個執行緒
            Thread innerThread = new Thread(() -> { //相當於心跳包
try {
                    while 
(true) { System.out.println("Do some thing for health check."); Thread.sleep(1_00000); //我們假設這是在發心跳包給連結 } } catch (InterruptedException e) { e.printStackTrace(); } }); innerThread.setDaemon(true);//守護執行緒是T,Daemon必須寫在start前面 innerThread.start();//
try { Thread.sleep(1_000); System.out.println("T thread finish done.");//T執行緒做的事情 } catch (InterruptedException e) { e.printStackTrace(); } }); t.setDaemon(true); 守護執行緒是main t.start(); }

先捋一捋上面的關係:

main--->裡面有T這個執行緒,---->裡面又包含--->InnerThread 這個執行緒

也就是說 --->main函式一旦停止--->T函式也停止----->T函式一旦停止---->InnerThread執行緒也就停止

這就叫做守護執行緒, 

回到上面的例子:也就是說T函式相當於一個連結,innerTheread是心跳包,當這個T連結停止的時候,Innder也就停止心跳包的傳送.

Join()方法介紹 :


上面的圖簡單說一下需求:也就是說我們是用來採集資料的,分別用了4個執行緒,最後把結果都寫到machines表中,但是這裡面沒一個執行緒花的時間都不一樣,所以就需要Join來寫:

Join把指定的執行緒加入到當前執行緒,可以將兩個交替執行的執行緒合併為順序執行的執行緒。

比如線上程B中呼叫了執行緒A的Join()方法,直到執行緒A執行完畢後,才會繼續執行執行緒B。

t.join();      //呼叫join方法,等待執行緒t執行完畢
t.join(1000);  //等待 t 執行緒,等待時間是1000毫秒。

模擬上面的需求:

public static void main(String[] args) throws InterruptedException {
        long startTimestamp = System.currentTimeMillis();//採集開始時間
//模擬多個執行緒去訪問資料庫
Thread t1 = new Thread(new CaptureRunnable("M1", 10000L));//需要花費這麼多時間
Thread t2 = new Thread(new CaptureRunnable("M2", 30000L));
Thread t3 = new Thread(new CaptureRunnable("M3", 15000L));
t1.start();//啟動各個執行緒
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
        long endTimestamp = System.currentTimeMillis();//採集結束時間
System.out.printf("Save data begin timestamp is:%s, end timestamp is:%s\n", startTimestamp, endTimestamp);
}

}

class CaptureRunnable implements Runnable { 

    private String machineName;//名稱
private long spendTime;//花費的時間
public CaptureRunnable(String machineName, long spendTime) {
        this.machineName = machineName;
        this.spendTime = spendTime;
}

    @Override
public void run() {
        //do the really capture data.
try {
            Thread.sleep(spendTime);//需要費時這麼長時間
System.out.printf(machineName + " completed data capture at timestamp [%s] and successfully.\n", System.currentTimeMillis());
} catch (InterruptedException e) {
            e.printStackTrace();
}
    }

    public String getResult() {
        return machineName + " finish.";
}
}

結果:

M1 completed data capture at timestamp [1521545947051] and successfully.
M3 completed data capture at timestamp [1521545952051] and successfully.
M2 completed data capture at timestamp [1521545967051] and successfully.

Save data begin timestamp is:1521545937048, end timestamp is:1521545967051

比如線上程B中呼叫了執行緒A的Join()方法,直到執行緒A執行完畢後,才會繼續執行執行緒B。

我們看到結果:

也就是說他們在等其他執行緒結束