多线程: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线程是否还存活。

猜你喜欢

转载自www.cnblogs.com/yangk1996/p/12679855.html