在Thread类的Api中,Join的作用是让当前线程等待目标线程结束之后才继续执行。

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。 
比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。 
想要更深入了解,建议看一下join的源码,也很简单的,使用wait方法实现的。

t.join(); //调用join方法,等待线程t执行完毕 
t.join(1000); //等待 t 线程,等待时间是1000毫秒。

分别是


public final synchronized void join(long millis, int nanos); //使当前线程等待目标线程millis 毫秒 ,nanos纳秒之后,当前线程继续执行。

public final synchronized void join(long millis); //使当前线程等待目标线程millis 毫秒,当前线程继续执行。

public final void join(); //使当前线程时刻检测目标线程,直到目标线程执行完成,再执行当前线程。

下面我们主要查看下 public final synchronized void join(long 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) {
      //如果等待的毫秒数为0,则通过Api, isAlive()时刻检测目标线程是否存活,若存活则继续等待。
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
        //判断目标线程是否存活,若存活,则等待mills毫秒,然后跳出join,当前线程执行。
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

从源码可以看出,就是当前线程在判断目标线程是否存活,如果存活根据参数的值,是无限等待到目标线程结束才执行当前线程,还是执行一段时间就开始执行当前线程。

public final void join();底层调用Join(0);实现无限等待知道目标线程结束。
 
下面再编写一个demo,先执行线程1,再执行线程2,最后执行线程3;
package com.dsx.thread;

public class TestThreadJoin {
public static void ThreadCreate(){
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("线程1执行了。。。");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}); final Thread t2 = new Thread(new Runnable() {
public void run() {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2执行了。。。。。");
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
try {
t2.join();
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程3执行了。。。。。。。");
}
});
t3.start();
t2.start();
t1.start();
}
public static void main(String[] args) {
ThreadCreate();
}
}


最新文章

  1. inline-block和float
  2. Latex中画出函数文件的调用关系拓扑图
  3. css清除浮动大全共8种方法
  4. Win10 VS2015自动添加头注释
  5. 腾讯云CentOS 6.6安装 Nginx
  6. 基于HTML5的燃气3D培训仿真系统
  7. Oracle常用命令1
  8. Unity3d,OnMouseDown()不执行的原因总结
  9. 第十三篇、Swift_Nav自定义返回按钮后或者隐藏导航栏,Pop返回手势失效的解决方法 Pop全局返回添加的方法
  10. effective c++(03)之const使用方法
  11. JS form表单提交的方法
  12. Charles_N:HTTP请求响应监听工具
  13. [ext4]08 磁盘布局 - CheckSums
  14. ARM总线方面知识
  15. Asp.net MVC在Razor中输出Html的两种方式
  16. Redis笔记-集群搭建
  17. git使用命令行拉取远程代码仓库中的分支至本地
  18. 小程序-setData
  19. day12 装饰器的模版
  20. GoLang学习控制语句之字符串

热门文章

  1. 对django框架架构和request/response处理流程的分析
  2. Drawing Graphs using Dot and Graphviz
  3. ffmpeg应用笔记
  4. [华为]查找两个字符串a,b中的最长公共子
  5. Cocos2d-JS实现的贪吃蛇
  6. Flask目录
  7. 解决升级到Xcode10,react native项目运行报错问题
  8. poj1151 Atlantis &amp;&amp; cdoj 1600艾尔大停电 矩形面积并
  9. python基础之多线程锁机制
  10. 从知乎了解到,为什么Mysql禁用存储过程、外键和级联?