java,多線程時用的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) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

以上是join()的底層代碼,在線程A內部調用線程B的join()函數時,會暫停A線程,等線程B執行結束后才會結束暫停。如果調用的join帶有時間參數,則時間計時結束也會結束wait()過程。

上面的isAlive()和wait()的函數對象是不一樣的,isAlive對象是被調用的線程B,wait(0)的對象是對應的是正在執行的線程A。

另一個要注意的點是,線程的狀態大致分為開始、就緒、運行、阻塞和死亡,isAlive()僅在就緒或者運行時算作真,故未start的線程join無效。

 

下面舉個例子

設置兩個線程類 ,並在一個子線程中調用另一個線程的join方法。

public class Thread1 extends Thread {
    public Thread1(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + ":"+i);
        }
    }
}
public class Thread2 extends Thread {
    public Thread2(String name) {
        super(name);
    }

    @Override
    public void run() {
        Thread1 B = new Thread1("B");
        B.start();
        try {
            B.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + ":"+i);
        }
    }
}

主類中按一定次序啟用線程

 

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        Thread2 A = new Thread2("A");
        Thread1 C = new Thread1("C");
        Thread1 D = new Thread1("D");
        Thread1 E = new Thread1("E");
        C.start();
        A.start();
        D.start();
        D.join();
        E.start();
    }
}

 

得到結果如下

 可以看到,在A中啟用B的join方法時,並未影響到主線程,主線程仍然向后運行並開啟了D,而A只能在B之后得到運行。主線程中啟用D的join方法后,則暫停執行,即E暫時無法start。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM