多线程编程之join()方法(含源码)

本文详细介绍了Java中线程的join方法的使用及工作原理。通过具体示例展示了如何利用join方法确保子线程完成后主线程再继续执行,包括join方法的源码解析及其与wait方法的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

join()方法:

在主线程创建并启动子线程,如果子线程需要太长时间,主线程会提前结束,等子线程完成run方法后,子线程结束。
但是有时候我们需要等待子线程完成后再执行主线程。例如:子线程处理一个数据,主线程需要取得这个数据,就需要使用join方法了。

package join;

public class MyThread extends Thread{
    public void run() {
        try {
            int secondValue=(int) (Math.random()*10000);
            System.out.println(secondValue);
            Thread.sleep(secondValue);

        }catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

}


package join;

public class Test {
    public static void main(String[] args) {
        try {
            MyThread mythread=new MyThread();
            mythread.start();
            mythread.join();

            System.out.println("mythread执行完输出☆☆☆☆☆");

        }catch(InterruptedException e) {
            e.printStackTrace();
        }

    }

}

控制台输出:
9808
mythread执行完输出☆☆☆☆☆

以上就是join的使用。
从join方法的特性我们了解到,join具有使得线程排队的效果,就像同步一样。但是join方法底层使用的是wait方法。
下面我们来看看join的源码:

public final void join() throws InterruptedException {
        join(0);
    }

对,没错这个就是join的源码。当然它调用了join(long millis)方法,所以下面来看一下join(long millis)方法:

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(long millis)方法的参数是0时,运行这个方法的线程就会执行wait(0)。我们再看看wait的源码:

 public final void wait() throws InterruptedException {
        wait(0);
    }

其实wait()方法其实执行的就是wait(0)。所以主线程一直等待。那么主线程是怎么被唤醒的呢?
我们看join(long milis)源码可以知道,这个方法使用synchronized修饰符的,也就是调用这个方法需要获得子线程对象的锁,然后调用wait,即先获得锁后释放锁,然后等待唤醒。
After run() finishes, notify() is called by the Thread subsystem.
当线程运行结束的时候,notify是被线程的子系统调用的

分别以普通对象和线程对象作为锁,当使用线程对象作为所得时候,如果锁对象执行完毕了。wait就会停止等待继续执行

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

        final MyLockThread mylockthread = new MyLockThread();

        //final Object mylockthread = new Object();
        new Thread(new Runnable() {

            @Override
            public void run() {
                synchronized (mylockthread) {
                    System.err.println(1);
                    try {
                        mylockthread.wait(0);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.err.println(2);
                }
            }
        }).start();

        mylockthread.start();
    }

    static class MyLockThread extends Thread {

        public MyLockThread() {
        }

        @Override
        public void run() {
            System.err.println("MyLockThread");
        }

    }
}

所以到现在我们知道了join的工作原理了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值