Thread 的 join() 源码解读

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

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 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3195 引用 • 8215 回帖
  • 线程
    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,当然是谁调用谁阻塞。

请输入回帖内容 ...

推荐标签 标签

  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    88 引用 • 122 回帖 • 622 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    132 引用 • 796 回帖
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖 • 6 关注
  • Gzip

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

    9 引用 • 12 回帖 • 169 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    133 引用 • 899 回帖
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 1 关注
  • 笔记

    好记性不如烂笔头。

    310 引用 • 794 回帖
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 489 关注
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 3 关注
  • OneDrive
    2 引用 • 1 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    143 引用 • 442 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 6 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 393 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 5 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 740 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    21 引用 • 245 回帖 • 230 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 653 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 608 关注
  • Access
    1 引用 • 3 回帖 • 3 关注