Thread的join方法[通俗易懂]

Thread的join方法[通俗易懂]Thread中的join方法主要的作用是让jion的线程加入当前线程,等加入的线程执行完之后才会执行当前线程。接下来看个例子:publicclassTestJoin{publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1=newThread(()->{try{Thr

大家好,又见面了,我是你们的朋友全栈君。

Thread中的join方法主要的作用是让jion的线程加入当前线程,等加入的线程执行完之后才会执行当前线程。

接下来看个例子:

public class TestJoin {

    public static void main(String[] args) throws InterruptedException {



        Thread t1 = new Thread(() ->
        {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("this is t1");
        });

        Thread t2 = new Thread(() -> {

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("this is t2");
        });


        Thread t3 = new Thread(() -> {
            System.out.println("this is t3");
        });

        t1.start();
        t2.start();
        t3.start();
        t1.join();
        t2.join();
        t3.join();
        System.out.println("运行结束");
    }

}

输出结果为:

this is t3
this is t1
this is t2
运行结束

可以看到输出是线程t1,t2,t3输出之后,才会输出到主线程。所以可以看出来join方法是把其他线程加入当前线程,等加入线程执行完之后才会执行当前线程。

如果想要t1,t2,t3再顺序输出,只需要在每个start方法后面再调用join就行了。这就就保证了每次主线程运行完一个线程,再去运行另外一个线程。

修改上面代码为:

public class TestJoin {

    public static void main(String[] args) throws InterruptedException {


        Thread t1 = new Thread(() ->
        {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("this is t1");
        });

        Thread t2 = new Thread(() -> {

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("this is t2");
        });


        Thread t3 = new Thread(() -> {
            System.out.println("this is t3");
        });

        t1.start();
        t1.join();
        t2.start();
        t2.join();
        t3.start();
        t3.join();
        System.out.println("运行结束");
    }

}

输出为:

this is t1
this is t2
this is t3
运行结束

 

接下来我们再从源码分析下Thread的join方法是怎么实现的:

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


    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方法,并且有一个while死循环,直到isAlive是False,也就是线程执行完成或者不存活。

顺带一提下Thread的yield的方法,此方法其实是只当前线程让出CPU回到就绪状态,线程再重新争抢CPU,但是结果可能是其他线程抢到CPU,也可能是自己抢到CPU。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136450.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm配置tensorflow环境_python3.6对应的tensorflow版本

    pycharm配置tensorflow环境_python3.6对应的tensorflow版本说明:如果只是为了入门学习TensorFlow框架,个人觉得,没必要上来就整GPU版本(主要是那个太复杂,安装真让人劝退),所以本文记录的是直接在pycharm里安装tensorflow,并运行demo。安装3.5或3.6版本的python,3.7及以上的版本貌似还不支持TensorFlow,博主用的是3.6.8版本,特别注意python还要求得是64位的,否则后面安装TensorFlow会…

    2022年8月29日
    0
  • python闭包详解_python闭包的使用场景

    python闭包详解_python闭包的使用场景闭包首先了解一下:如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用

    2022年8月6日
    2
  • java测试案例编写方法_java实现自动化测试实例

    java测试案例编写方法_java实现自动化测试实例1.定义一个测试类(测试用例)1.1测试类名:被测试类的名字+Test比如UserServiceImplTest1.2测试类的包名:最后以.test结尾比如xxx.xx.test2.测试类中的测试方法2.1test+方法名比如testAdd2.2返回值建议void因为独立运行没有调用返回值没有意义2.3同上没有调用自然也不会有人传参参数建议…

    2022年10月10日
    0
  • Controlling Broadcasts and Multicasts

    Controlling Broadcasts and Multicasts为什么80%的码农都做不了架构师?>>>…

    2022年6月24日
    20
  • Java单例模式中双重检查锁的问题

    Java单例模式中双重检查锁的问题单例创建模式是一个通用的编程习语。和多线程一起使用时,必需使用某种类型的同步。在努力创建更有效的代码时,Java程序员们创建了双重检查锁定习语,将其和单例创建模式一起使用,从而限制同步代码量。然而,由于一些不太常见的Java内存模型细节的原因,并不能保证这个双重检查锁定习语有效。它偶尔会失败,而不是总失败。此外,它失败的原因并不明显,还包含Java内存模型的一些隐秘细节。这些事实将导致代

    2022年7月25日
    13
  • 面向对象设计

    面向对象设计

    2021年11月28日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号