Thread 的 join() 源码解读

本贴最后更新于 2934 天前,其中的信息可能已经时移世改

join()使用场景

当程序希望各个线程执行完后,将他们的计算结果最终合并运算时,换句话说要等待多个线程将子任务执行完后,才能进行合并结果操作,这时候就可以使用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 &lt; 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay &lt;= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }<br /><br /></pre>

有同学疑问,调用join后到底是哪个线程阻塞了?其实很好理解,就是当前执行的线程阻塞,而不是调用join的线程!

public static void main(String[] args) throws InterruptedException {
		final Thread t = new Thread(new Runnable() {
			public void run() {
				try {
					System.out.println("t线程开始"+System.currentTimeMillis());
					Thread.sleep(2000);
					System.out.println("t线程结束"+System.currentTimeMillis());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
Thread t2 = new Thread(new Runnable() { public void run() { try { t.start(); t.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2线程结束"+System.currentTimeMillis()); } }); t2.start();</pre>

                  Thread.currentThread().sleep(1000);
                  System.out.println(t2.getState());

		System.out.println("t2线程开始"+System.currentTimeMillis());
}</pre>


将上面的测试代码里的join方法,用join的源码替换就一目了然了如下

public static void main(String[] args) throws InterruptedException {
		final Thread t = new Thread(new Runnable() {
			public void run() {
				try {
					System.out.println("t线程开始"+System.currentTimeMillis());
					Thread.sleep(2000);
					System.out.println("t线程结束"+System.currentTimeMillis());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
Thread t2 = new Thread(new Runnable() { public void run() { try { t.start(); //t.join(); //join源码开始 long millis = 0; long base = System.currentTimeMillis(); long now = 0; if (millis &lt; 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (t.isAlive()) { //wait就是对t2线程的操作 t.wait(0); } } else { while (t.isAlive()) { long delay = millis - now; if (delay &lt;= 0) { break; } t.wait(delay); now = System.currentTimeMillis() - base; } } } catch (InterruptedException e) { e.printStackTrace(); }//join源码结束 System.out.println("t2线程结束"+System.currentTimeMillis()); } }); t2.start(); System.out.println("t2线程开始"+System.currentTimeMillis()); }</pre>

 

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖
  • 线程
    122 引用 • 111 回帖 • 3 关注
  • join
    6 引用 • 21 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • zempty 1 via U9500

    嘿嘿,我猜你是看了上一篇文章才有了这篇吧。猜对了求感谢

  • someone 1

    感谢[em01]

  • wanglei0622
    作者

    @zempty 感谢居然要积分,有点舍不得

  • wanglei0622 1
    作者

    @zempty 感谢居然要积分,有点舍不得

  • zempty via U9500

    @wanglei0622 我会回感的,然而我却感给系统那个默认评论者,浪费了。

  • someone

    没事[em01]

  • someone

    这两天我下注,赢了400分[em01],今天不下了,有种不祥的预感

  • zempty via U9500

    @Default Commenter 你是一下用博客回复,一下用社区回复么?

  • wanglei0622
    作者

    @88250 还有个建议,个人博客回复评论的数据同步时,博主的账号不能和社区的账号绑定么,
    请看这个帖子的回复例子

  • wanglei0622
    作者

    @zempty 是啊 ,因为我直接从邮件里面点进去的,进入的是我的博客

  • 88250

    @wanglei0622 区分不了身份,身份会被伪造,安全问题

  • someone

    为什么发帖人可以呢

  • wizardforcel

    简单来说就是 join 里面调用了 wait,当然是谁调用谁阻塞。

请输入回帖内容 ...

推荐标签 标签

  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    56 引用 • 25 回帖 • 3 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 684 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 567 关注
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 10 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 179 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 595 回帖 • 1 关注
  • danl
    168 关注
  • BND

    BND(Baidu Netdisk Downloader)是一款图形界面的百度网盘不限速下载器,支持 Windows、Linux 和 Mac,详细介绍请看这里

    107 引用 • 1281 回帖 • 29 关注
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    24541 引用 • 100487 回帖
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 703 关注
  • 安全

    安全永远都不是一个小问题。

    203 引用 • 816 回帖 • 1 关注
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 116 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    84 引用 • 324 回帖
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 365 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 29 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 18 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 170 关注
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 168 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 815 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 522 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 264 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    31 引用 • 108 回帖
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 653 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 84 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 139 关注