java中join方法的理解和说明

前言:

java 中的 join() 方法在多线程中会涉及到,这个方法最初理解起来可能有点抽象,用一两次大概就懂了。简单说就是当前线程等待调用join方法的线程结束才能继续往下执行

1. 举个例子

如下

public class MyRunnable implements Runnable {
    private int num;
    private String threadName;
    private long result;

    public MyRunnable(int num, String threadName) {
        this.threadName = threadName;
        this.num = num;
    }

    public void run() {
        for (int i = 0; i < num; i++) {
            result += i;
        }
    }


    public long getResult() {
        return result;
    }
}
MyRunnable 类是实现 Runnable 接口的多线程类,其run() 方法的计算跟类的num 字段相关,计算值存储在 result 字段里面,如果想获取计算结果就必须等线程执行完之后调用 getResult() 获取,常规方式如下

public class JoinTest {
    public static void main(String[] args) {

        normal();

    }

    private static void normal() {
        MyRunnable myRunnable_1 = new MyRunnable(10000, "runnable_1");

        Thread thread_1 = new Thread(myRunnable_1);
        thread_1.start();

        do {
            System.out.println("--------------------------------------------------");
            System.out.println("thread status:  " + thread_1.isAlive() + ",result: " + myRunnable_1.getResult());
        } while (thread_1.isAlive());
    }
}

需要持续判断线程 thread_1 是否结束才能最终获取计算结果,输出如下:

--------------------------------------------------
thread status:  true,result: 0
--------------------------------------------------
thread status:  true,result: 11026
--------------------------------------------------
thread status:  false,result: 499500

而使用join()方法可以省去判断的麻烦,如下


public class JoinTest {
    public static void main(String[] args) {

        join();

    }


    private static void join() {

        MyRunnable myRunnable_1 = new MyRunnable(10000, "runnable_1");

        Thread thread_1 = new Thread(myRunnable_1);
        thread_1.start();

        try {
            thread_1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("thread status:  " + thread_1.isAlive() + ",result: " + myRunnable_1.getResult());

    }
}

输出如下:

thread status:  false,result: 49995000

调用join方法以后当前线程(在这里就是main函数)会等待thread_1 结束后才继续执行下面的代码。

2. jion() 方法源码解析

其实 join() 方法内部的实现跟上面例子中的normal()方法很类似,也是使用线程的 isAlive() 方法来判断线程是否结束,核心源码如下:

    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) {                // join 方法如果不传参数会默认millis 为 0
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

当然上述还涉及 Object 类的 wait() 方法,感兴趣可以查一下,这里可以简单的理解就是一个等待多少时间。

上一篇:JAVA学习第二十二天


下一篇:JAVA多线程之线程安全