美文网首页JAVA基础(未看)
Java多线程-Thread.join()

Java多线程-Thread.join()

作者: caibixiang | 来源:发表于2018-07-01 14:14 被阅读24次

Java多线程-Thread.join()

Thread.join()把制定的线程加入到当前线程,可以将两个交替执行的多线程合并为顺序执行的线程。比如在线程B中调用累线程A的join()方法,直到线程A执行完毕后,才会继续执行线程B;

eg:

线程A代码:

public class A extends Thread{

@Override

        public void run() {

           for (int i =0; i <500 ; i++) {

         System.out.println("A--thread:"+i);

           }

}

}

线程B的代码:

public class Bextends Thread {

@Override

    public void run() {

A a =new A();

a.start();

try {

           a.join();// 调用join方法

            for (int i =0; i <500 ; i++) {

         System.out.println("Thread-B:"+i);

}

}catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args){

new B().start();

}

}

观察结果:在线程B的run方法中启动类线程A的start方法和join(),打印的结果没有交叉执行。可以得出上面的结论。感兴趣的同学可以将线程a.join()方法注视掉,观看打印结果有没有交叉执行。   

结论:   当我们调用某个线程的join这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行

源码解析:

Thread 源码有3个join方法重载。

public final void join()throws InterruptedException {

join(0);

};

public final synchronized void join(long millis,int nanos)

throws InterruptedException {

if (millis <0) {

throw new IllegalArgumentException("timeout value is negative");

}

if (nanos <0 || nanos >999999) {

throw new IllegalArgumentException(

"nanosecond timeout value out of range");

}

if (nanos >=500000 || (nanos !=0 && millis ==0)) {

millis++;

}

join(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;

}

}

其中

a. join() 和 join(long millis, int nanos) 最后都调用了 join(long millis)。

b. 带参数的 join() 都是 synchronized method。

c. join() 调用了 join(0),从源码可以看到 join(0) 不断检查当前线程(join() 所属的线程实例,非调用线程)是否是 Active。

d. join() 和 sleep() 一样,都可以被中断(被中断时,会抛出 InterrupptedException 异常);不同的是,join() 内部调用了 wait(),会出让锁,而 sleep() 会一直保持锁。

以本文开头的代码为例,我们分析一下代码逻辑:

B 调用 a.join(),a.join() 再调用 a.join(0) (此时 B 会获得 child 实例作为锁,其他线程可以进入 child.join() ,但不可以进入 child.join(0)(同步的), 因为无法获取锁)。child.join(0) 会不断地检查 child 线程是否是 Active。

如果 child 线程是 Active,则循环调用 child.wait(0)(为了防止 Spurious wakeup, 需要将 wait(0) 放入 for 循环体中;此时 B 会释放 a 实例锁,其他线程可以竞争锁并进入 a.join(0)。我们可以得知,可以有多个线程等待某个线程执行完毕)。

一旦 a 线程不为 Active (状态为 TERMINATED), a.join(0) 会直接返回到 a.join(), a.join() 会直接返回到 B 父线程,B 父线程就可以继续运行下去了。

相关文章

  • Java多线程-Thread.join()

    Java多线程-Thread.join() Thread.join()把制定的线程加入到当前线程,可以将两个交替执...

  • Java中如何让多线程按照自己指定的顺序执行

    1、Java中如何让多线程按照自己指定的顺序执行? 方法1: 通过thread.join的方法来实现 thread...

  • java并发工具类

    等待多线程完成 主线程等待所有线程完成工作 实现 thread.join()方法 原理 join 用于让当前执行线...

  • Java线程不常用的方法

    一、概述 Java线程中有些低频使用的方法,比如 thread.join() thread.interupt() ...

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 社招遇到的问题

    java 集合类继承体系:集合类继承体系 java 中子线程执行完成后再唤醒主线程: thread.join 或 ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • 多线程之间的通信

    一般我们多线程的通信方式 我们可以根据加锁进行限制线程的先后,比如, thread.join() 方法用synch...

  • Java多线程目录

    Java多线程目录 Java多线程1 线程基础Java多线程2 多个线程之间共享数据Java多线程3 原子性操作类...

  • java多线程--Callable

    **移步[java多线程系列文章]Java多线程(二十二)---LockSupport工具Java 停止线程 一、...

网友评论

    本文标题:Java多线程-Thread.join()

    本文链接:https://www.haomeiwen.com/subject/shouyftx.html