一、作用

  Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。具体看代码:

  

public class JoinTest {public static void main(String [] args) throws InterruptedException {ThreadJoinTest t1 = new ThreadJoinTest("小明");ThreadJoinTest t2 = new ThreadJoinTest("小东");t1.start();/**join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思就是:程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会*/t1.join();t2.start();}}
class ThreadJoinTest extends Thread{public ThreadJoinTest(String name){super(name);}@Overridepublic void run(){for(int i=0;i<1000;i++){System.out.println(this.getName() + ":" + i);}}
}

上面程序结果是先打印完小明线程,在打印小东线程;  

上面注释也大概说明了join方法的作用:在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。注意,这里调用的join方法是没有传参的,join方法其实也可以传递一个参数给它的,具体看下面的简单例子:

public class JoinTest {public static void main(String [] args) throws InterruptedException {ThreadJoinTest t1 = new ThreadJoinTest("小明");ThreadJoinTest t2 = new ThreadJoinTest("小东");t1.start();/**join方法可以传递参数,join(10)表示main线程会等待t1线程10毫秒,10毫秒过去后,* main线程和t1线程之间执行顺序由串行执行变为普通的并行执行*/t1.join(10);t2.start();}}
class ThreadJoinTest extends Thread{public ThreadJoinTest(String name){super(name);}@Overridepublic void run(){for(int i=0;i<1000;i++){System.out.println(this.getName() + ":" + i);}}
}

上面代码结果是:程序执行前面10毫秒内打印的都是小明线程,10毫秒后,小明和小东程序交替打印。

所以,join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。

  

  二、join与start调用顺序问题

  上面的讨论大概知道了join的作用了,那么,入股 join在start前调用,会出现什么后果呢?先看下面的测试结果

public class JoinTest {public static void main(String [] args) throws InterruptedException {ThreadJoinTest t1 = new ThreadJoinTest("小明");ThreadJoinTest t2 = new ThreadJoinTest("小东");/**join方法可以在start方法前调用时,并不能起到同步的作用*/t1.join();t1.start();//Thread.yield();t2.start();}}
class ThreadJoinTest extends Thread{public ThreadJoinTest(String name){super(name);}@Overridepublic void run(){for(int i=0;i<1000;i++){System.out.println(this.getName() + ":" + i);}}
}

上面代码执行结果是:小明和小东线程交替打印。

所以得到以下结论:join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解:如果一个线程都没有start,那它也就无法同步了。

  三、join方法实现原理

  有了上面的例子,我们大概知道join方法的作用了,那么,join方法实现的原理是什么呢?

  其实,join方法是通过调用线程的wait方法来达到同步的目的的。例如,A线程中调用了B线程的join方法,则相当于A线程调用了B线程的wait方法,在调用了B线程的wait方法后,A线程就会进入阻塞状态,具体看下面的源码:

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

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

Thread 的join方法解释相关推荐

  1. Thread的join方法

    Thread中的join方法主要的作用是让jion的线程加入当前线程,等加入的线程执行完之后才会执行当前线程. 接下来看个例子: public class TestJoin {public stati ...

  2. 多线程中Thread的join方法

    多线程中Thread的join方法 join简介 join方法是Thread类中的一个方法,该方法的定义是等待该线程执行直到终止.其实就说join方法将挂起调用线程的执行,直到被调用的对象完成它的执行 ...

  3. 多线程--关于Thread的join方法

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.Thread的join方法. 二.方便理解引入例子 1.代码示例 2.输出结果 总结 一.Thread的join方法. ...

  4. java thread join_java中thread的join方法为什么能让线程插队

    在面试中经常会遇到这样的问题:在主线程中有两个子线程,如果能让着两个子线程能顺序的执行? 答案自然是用join来使得两个线程顺序执行,先看一下具体代码 public class ThreadOfJoi ...

  5. Thread的join方法使用解析

    在C#中,Thread用的是比较多的,至少在windows form中使用是比较频繁的.一说到线程,可能马上就会想到界面和线程交互的头疼事,多线程之前数据共享,线程异步等等.这些当然是比较头疼的,只要 ...

  6. java 线程 thread.join_java线程Thread的join方法。

    1,方法的作用: 父线程等待子线程的执行. 如果是join或者join(0),即等待时长是0,父线程就会一直等到子线程执行结束, 如果是join(time),即等待时长是time数值,那父线程实际等待 ...

  7. java join使用实例_Java多线程中关于join方法的使用实例解析

    先上代码 新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String ...

  8. 【总结】C# 线程同步技术(一)之 Join 方法

    最近工作闲暇之际,翻阅了以前保存的电子书<C#多线程编程手册>,发现此书同步技术这块写的甚好,于是参考此书并结合实例,对同步技术做一下总结和分析,也算是读书笔记与心得体会吧,并与大家分享. ...

  9. JAVA多线程基础篇-join方法的使用

    1.概述 join()是Thread类中的一个方法,它的作用是将当前线程挂起,等待其他线程结束后再执行当前线程,即当前线程等待另一个调用join()方法的线程执行结束后再往下执行.通常用于在main主 ...

最新文章

  1. 2021高考萧山二中成绩查询,萧山中学2018高考成绩
  2. MongoDB基础教程系列--目录结构
  3. iPhone 7卖点不多出货量下降?剧透分析师又发报告
  4. #1081 : 最短路径·一(Dijkstra)
  5. F#与ASP.NET(1):基于事件的异步模式与异步Action
  6. Redis凭啥这么快?只能做缓存?架构师道出了真相(颠覆你的认知)
  7. 编辑器eslint格式_vscode保存代码,自动按照eslint规范格式化代码设置
  8. XmlReader 内部使用NameTable
  9. 终于有人把 5G 和边缘计算的关系说清楚了! | 技术头条
  10. 第 0 章 Readme
  11. 数据结构之链表及实现
  12. Java递归算法求n的阶乘
  13. go微服务调用报错too many colons in address
  14. wps2016向程序发送命令_老司机帮您向程序发送命令时出现错误 【操作步骤】 的设置办法...
  15. 消费者人群画像 python_如何正确打开相似人群画像算法
  16. 心态很容易受别人影响_太容易被别人影响,我上辈子可能是个“复印机”
  17. Chrome调试以及选择清除缓存刷新
  18. 35岁测试工程师,公司因疫情降本增效被辞退
  19. 十级龙王间的决斗(C++)
  20. 感受大自然帶給我們的愉悅心情

热门文章

  1. DOS - 批处理之 for /f 中的 delims 和 tokens
  2. 在哪里创业与怎么创业
  3. ElasticSearch使用详解
  4. class meta ordering 的使用
  5. python测颜值(优良中差不及格)?敢不敢来一发
  6. 【知识图谱 Knowledge Graph】从它的起源看未来的研究方向。知识图谱——科普篇
  7. java类和接口的区别
  8. 猎豹移动CTO:以云为基础锚定内容新市场
  9. STL学习--vector的学习
  10. 让万圣节更可怕,玩乐一晚的恐怖电影派对主题