java線程join方法使用方法簡介


本博客簡介介紹一下java線程的join方法,join方法是實現線程同步,可以將原本並行執行的多線程方法變成串行執行的

如圖所示代碼,是並行執行的

public class ThreadTest {
    //private static final Long count = 10000L;
    public static void main(String[] args){
        long base = System.currentTimeMillis();
        try {
            ThreadJoin t1 = new ThreadJoin("線程1");
            ThreadJoin t2 = new ThreadJoin("線程2");
            t1.start();
            t2.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
        long time = System.currentTimeMillis() - base;
        System.out.println("執行時間:"+time);
    }
    
}
class ThreadJoin extends Thread{
    private static final Long count = 10L;

    public ThreadJoin(String name){
        super(name);
    }

    @Override
    public void run() {
        //super.run();
        for(int i = 1; i <= count; i ++){
            System.out.println(this.getName()+":"+i);
        }
    }
}

打印出來的信息,都是這樣的

執行時間:0
線程1:1
線程2:1
線程2:2
線程2:3
線程2:4
線程2:5
線程2:6
線程2:7
線程2:8
線程2:9
線程2:10
線程1:2
線程1:3
線程1:4
線程1:5
線程1:6
線程1:7
線程1:8
線程1:9
線程1:10

要實現串行執行,可以加上join方法,實現線程1執行完成后才開始執行線程2,也就是串行執行

public class ThreadTest {
    //private static final Long count = 10000L;
    public static void main(String[] args){
        long base = System.currentTimeMillis();
        try {
            ThreadJoin t1 = new ThreadJoin("線程1");
            ThreadJoin t2 = new ThreadJoin("線程2");
            t1.start();
            t1.join();
            t2.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
        long time = System.currentTimeMillis() - base;
        System.out.println("執行時間:"+time);
    }
    
}
class ThreadJoin extends Thread{
    private static final Long count = 10L;

    public ThreadJoin(String name){
        super(name);
    }

    @Override
    public void run() {
        //super.run();
        for(int i = 1; i <= count; i ++){
            System.out.println(this.getName()+":"+i);
        }
    }
}
線程1:1
線程1:2
線程1:3
線程1:4
線程1:5
線程1:6
線程1:7
線程1:8
線程1:9
線程1:10
執行時間:0
線程2:1
線程2:2
線程2:3
線程2:4
線程2:5
線程2:6
線程2:7
線程2:8
線程2:9
線程2:10


從執行結果看,已經是串行執行線程

所以上面的例子是調了現場1的join方法,也就是說要先執行完成線程1,然后才執行main主線程

join方法的作用是,舉個例子,在A線程里調B線程的join方法時,要先B線程執行完成,然后才會繼續執行A線程

ok,上面調join方法是不加參數的,也可以加上參數,比如線程A.join(10);,就是說線程A執行10s后,繼續執行B線程

注意:join時間參數缺省的情況,默認是0,也就是說join()等同於join(0);

/**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join() throws InterruptedException {
        join(0);
    }

Thread類里的源碼,可以看出默認賦值為0,然后這個0是什么意思?0不是表示執行0s,而是表示要A線程執行完成才繼續執行B線程的意思

ok,然后為什么調用了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");
        }
		//執行時間為0或者缺省情況
        if (millis == 0) {
            while (isAlive()) {//表示線程還沒執行好
                wait(0);//調用線程的wait方法
            }
        } else {//執行時間大於0的情況
            while (isAlive()) {
                long delay = millis - now;//循環計算延期時間
                if (delay <= 0) {
                    break;
                }
                wait(delay);//同樣調用線程的wait方法
                now = System.currentTimeMillis() - base;
            }
        }
    }

ok,看了一下源碼,還是比較容易理解的,其實就是調用了現場wait方法實現線程同步的


免責聲明!

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



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