美文网首页
主线程等待子线程执行完成后再执行——Thread.join()

主线程等待子线程执行完成后再执行——Thread.join()

作者: 微子Lee | 来源:发表于2018-01-07 21:52 被阅读0次

一、一个例子

private static void joinTest(List<String> roles) {
Vector<Thread> vector = new Vector<>(10);
for (int i=0;i<10;i++){
MyThread myThread = new MyThread("id"+i,"name"+i,roles);
Thread t = new Thread(myThread);
vector.add(t);
t.start();
}
for (Thread thread : vector){
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class MyThread implements Runnable{

private String id;
private String name;
private List<String> roles;

public MyThread(String id,String name,List<String> roles){
    this.name = name;
    this.id = id;
    this.roles = roles;
}

@Override
public void run() {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    roles.add(name);
    System.out.println("执行了-id:"+id+"name:"+name+"roles size:"+roles.size());
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<String> getRoles() {
    return roles;
}

public void setRoles(List<String> roles) {
    this.roles = roles;
}

}
输出结果:

开始:1515250426924
执行了-id:id2name:name2roles size:1
执行了-id:id1name:name1roles size:3
执行了-id:id0name:name0roles size:2
执行了-id:id4name:name4roles size:4
执行了-id:id6name:name6roles size:7
执行了-id:id7name:name7roles size:8
执行了-id:id8name:name8roles size:9
执行了-id:id5name:name5roles size:6
执行了-id:id3name:name3roles size:5
执行了-id:id9name:name9roles size:10
[name2, name0, name1, name4, name3, name5, name6, name7, name8, name9]
结束:1515250427932耗时:1008roles size:10
可以看出,上面每个线程执行1000ms,总时长1008ms.

二、源码分析

/**

  • Waits for this thread to die.
  • <p> An invocation of this method behaves in exactly the same
  • way as the invocation
  • <blockquote>
  • {@linkplain #join(long) join}{@code (0)}
  • </blockquote>
  • @throws InterruptedException
  •      if any thread has interrupted the current thread. The
    
  •      <i>interrupted status</i> of the current thread is
    
  •      cleared when this exception is thrown.
    

*/
public final void join() throws InterruptedException {
join(0);
}
这里看清楚一点:join传参为0。

然后进入join方法:

/**

  • Waits at most {@code millis} milliseconds for this thread to
  • die. A timeout of {@code 0} means to wait forever.
  • <p> This implementation uses a loop of {@code this.wait} calls
  • conditioned on {@code this.isAlive}. As a thread terminates the
  • {@code this.notifyAll} method is invoked. It is recommended that
  • applications not use {@code wait}, {@code notify}, or
  • {@code notifyAll} on {@code Thread} instances.
  • @param millis
  •     the time to wait in milliseconds
    
  • @throws IllegalArgumentException
  •      if the value of {@code millis} is negative
    
  • @throws InterruptedException
  •      if any thread has interrupted the current thread. The
    
  •      <i>interrupted status</i> of the current thread is
    
  •      cleared when this exception is thrown.
    

*/
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;
    }
}

}
从源码可以看出,如果线程被生成了,但还未被起动,isAlive()将返回false,调用它的join()方法是没有作用的,将直接继续向下执行wait。而wait方法中有参数,也就是不用唤醒谁,只是不再执行wait,向下继续执行而已。

三、join总结

join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。

相关文章

  • 社招遇到的问题

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

  • 主线程等待子线程执行完成后再执行——Thread.join()

    一、一个例子 private static void joinTest(List roles) {Vector ...

  • JAVA线程相关

    thread.join() 等待thread线程执行完才继续向下执行代码,但是可以执行之前的线程Thread.sl...

  • juc多线程

    1、join:待此线程执行完成后,再执行其他线程,其他线程阻塞等待 CyclicBarrier 等所有线程都到达了...

  • 线程总结

    daemon守护线程 当主线程执行完成后,守护线程不管是否完成,立即终止。 join 当前主线程等待子线程执行完成...

  • java并发工具类

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

  • Java基础(五)-多线程-2

    问:如何实现子线程先执行,主线程再执行答: 启动子线程后,立即调用该线程的join()方法,则主线程必须等待子线程...

  • Thread基础知识

    Thread.join() 将线程A加入到当前执行线程中,只有当线程A执行完毕,当前线程才能继续执行; join方...

  • JAVA面试锦集01-如何保证线程的顺序

    1、Thread.join() 方法 调用Object.wait()方法,他的目的是暂停主线程,等待执行完子...

  • Java多线程 - 第三章

    join方法 先看下面代码,观察控制台输出 可以看到主线程与子线程依次执行输出,如何让主线程在子线程完成后再执行呢...

网友评论

      本文标题:主线程等待子线程执行完成后再执行——Thread.join()

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