• 多线程:Join的理解


    多线程Join的理解

    ​ 开发中使用多线程也非常少,之前因为有一个调取两个摄像头获取每帧进行活体检测时候,有人给了思路说到Join这个关键字,我才仔细的研究了一下这个。以前理解的意思是:使用join关键字,就是相当于调用join的线程如果没有执行完毕,其他线程都处于等待状态。这就相当是把线程串起来了一样。看了很多的博客,后面理解的是:那个线程等待挂起,取决与在那个线程上面调用XX.join,并不是影响到所有的线程。

    • 代码演示(正常线程执行)
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("A" + "-" + i);
                }
            });
            Thread t2 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("B" + "-" + i);
                }
            });
            t1.start();
            t2.start();
        }
    console
    A-1
    B-1
    B-2
    B-3
    B-4
    B-5
    A-2
    A-3
    A-4
    A-5
    
    • 当在t2线程前面使用join
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("A" + "-" + i);
                }
            });
            Thread t2 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("B" + "-" + i);
                }
            });
            t1.start();
            t1.join();
            t2.start();
        }
        console
    A-1
    A-2
    A-3
    A-4
    A-5
    B-1
    B-2
    B-3
    B-4
    B-5
    

    当在t2线程前面,main线程调用了t1线程的join,所以会让main线程暂时挂起。从而需要等到t1线程死亡之后才可以唤醒main线程继续执行下去

    • 当把join放在t2线程后面
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("A" + "-" + i);
                }
            });
            Thread t2 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("B" + "-" + i);
                }
            });
            Thread t3 = new Thread(() -> {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("C" + "-" + i);
                }
            });
            t1.start();
            t2.start();
            t1.join();
            t3.start();
        }
    console
        A-1
    A-2
    B-1
    A-3
    B-2
    A-4
    B-3
    B-4
    B-5
    A-5
    C-1
    C-2
    C-3
    C-4
    C-5
    

    无论执行多次,都可证实一点,在main线程中调用xx.join的时候挂起的是main线程,但是挂起main线程之前的执行的线程不受影响。

    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方法
                    wait(0);
                }
            } else {
                //判断线程是否处于活动状态
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    //调用线程的wait方法
                    wait(delay);
                    now = System.currentTimeMillis() - base;
               }
            }
        }
    

    wait()的作用是让当前线程去等待。wait方法是object类中的方法,调用该方法是让获得当前对象锁的线程等待,而在t1.join()时,是在主线程中进行调用了,主线程获得join方法上的对象锁。

    isAlive()这个方法调用的是t1从Thread类中继承的native方法,是一种普通的方法调用,所以它判断的是t1线程是否还存活。

  • 相关阅读:
    maven 错误:读取 xxx.jar 时出错;invalid LOC header (bad signature) 1 错误
    设计模式总结篇系列:建造者模式(Builder)
    java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to
    Rxlifecycle使用详解,解决RxJava内存泄露问题
    详细解析RxAndroid的使用方式
    Android开源项目:GifView——Android显示GIF动画
    Rxjava2的学习与总结
    Pycharm连接gitlab
    Pycharm+Django+Python+MySQL开发 后台管理数据库
    Django-Model操作数据库(增删改查、连表结构)
  • 原文地址:https://www.cnblogs.com/yangk1996/p/12679855.html
Copyright © 2020-2023  润新知