java join()用法示例

作用:可以让我们在执行一个方法前,先执行另外一个方法,或者说,可以帮我们把一些并行执行的过程改为串行执行。

1.示例如下:

主线程执行一段时间后,需要先执行一个子线程里的任务,然后再执行主线程。
测试类

package com.java4all.controller;

/**
 * Author: yunqing
 * Date: 2018/7/31
 * Description:
 */
public class Test1 {

    public static void main(String[] args){
        try {
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务前1");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务前2");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务前3");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务前4");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务前5");
            MyThread myThread = new MyThread();
            myThread.start();
            myThread.join();
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务后1");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务后2");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务后3");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务后4");
            System.out.println(Thread.currentThread().getName()+"======>主线程在执行任务后5");
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }


}

子线程类

package com.java4all.controller;

/**
 * Author: yunqing
 * Date: 2018/7/31
 * Description:
 */
public class MyThread extends Thread{
    @Override
    public void run() {
        for(int i = 0; i < 20; i ++){
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName()+"======>子线程在执行任务:"+i);
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }

}

执行结果为:

main======>主线程在执行任务前1
main======>主线程在执行任务前2
main======>主线程在执行任务前3
main======>主线程在执行任务前4
main======>主线程在执行任务前5
Thread-0======>子线程在执行任务:0
Thread-0======>子线程在执行任务:1
Thread-0======>子线程在执行任务:2
Thread-0======>子线程在执行任务:3
Thread-0======>子线程在执行任务:4
Thread-0======>子线程在执行任务:5
Thread-0======>子线程在执行任务:6
Thread-0======>子线程在执行任务:7
Thread-0======>子线程在执行任务:8
Thread-0======>子线程在执行任务:9
Thread-0======>子线程在执行任务:10
Thread-0======>子线程在执行任务:11
Thread-0======>子线程在执行任务:12
Thread-0======>子线程在执行任务:13
Thread-0======>子线程在执行任务:14
Thread-0======>子线程在执行任务:15
Thread-0======>子线程在执行任务:16
Thread-0======>子线程在执行任务:17
Thread-0======>子线程在执行任务:18
Thread-0======>子线程在执行任务:19
main======>主线程在执行任务后1
main======>主线程在执行任务后2
main======>主线程在执行任务后3
main======>主线程在执行任务后4
main======>主线程在执行任务后5

可以看到,主线程执行一段时间后,子线程调用了join()方法,此时主线程阻塞,直到子线程执行完毕,主线程才继续执行。

2.原理

我们查看一下Thread.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;
            }
        }
    }

其实是通过wait来实现的,当发现子线程还活着时,那主线程就一直等待。

3.另一种用法

当我们在join()方法中传入参数时,比如1000,那么主线程只会阻塞1000ms,然后就恢复了并行的执行状态。
如果我们把上面的代码改为:

myThread.join(1000);

那么结果为:

main======>主线程在执行任务前1
main======>主线程在执行任务前2
main======>主线程在执行任务前3
main======>主线程在执行任务前4
main======>主线程在执行任务前5
main======>主线程在执行任务后1
main======>主线程在执行任务后2
main======>主线程在执行任务后3
main======>主线程在执行任务后4
main======>主线程在执行任务后5
Thread-0======>子线程在执行任务:0
Thread-0======>子线程在执行任务:1
Thread-0======>子线程在执行任务:2
Thread-0======>子线程在执行任务:3
Thread-0======>子线程在执行任务:4
Thread-0======>子线程在执行任务:5
Thread-0======>子线程在执行任务:6
Thread-0======>子线程在执行任务:7
Thread-0======>子线程在执行任务:8
Thread-0======>子线程在执行任务:9
Thread-0======>子线程在执行任务:10
Thread-0======>子线程在执行任务:11
Thread-0======>子线程在执行任务:12
Thread-0======>子线程在执行任务:13
Thread-0======>子线程在执行任务:14
Thread-0======>子线程在执行任务:15
Thread-0======>子线程在执行任务:16
Thread-0======>子线程在执行任务:17
Thread-0======>子线程在执行任务:18
Thread-0======>子线程在执行任务:19

猜你喜欢

转载自blog.csdn.net/weixin_39800144/article/details/81316524