前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Java并发编程之join方法的使用

Java并发编程之join方法的使用

作者头像
布禾
发布于 2021-03-15 13:56:06
发布于 2021-03-15 13:56:06
54100
代码可运行
举报
运行总次数:0
代码可运行
简介

在多线程编程中,有时候一个线程的执行可能要依赖于另外一个线程的执行结果才能执行,JDK提供了join方法来实现这种功能。

当我们在线程上调用join方法时,调用线程进入等待状态。它保持等待状态,直到引用的线程执行完成。

join及其重载方法:

  1. join(),等待该线程执行结束。
  2. join(long millis),类似join()方法,多了一个millis参数,表示最多等待该线程执行的毫秒数,join(0)等价于join()。
  3. join(long millis, int nanos),同join(long millis)方法,只是等待时间有了更高的精度。
join方法的基本使用

等待子线程结束,主线程再继续执行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("数据加载中...");
        });

        thread.start();
        thread.join();

        System.out.println("数据加载完毕");
    }
}

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
数据加载中...
数据加载完毕

设置最长等待时间,超过该时间后,主线程将继续执行,而不会等子线程结束再执行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("数据加载中...");
        });

        thread.start();
        thread.join(1000);

        System.out.println("数据加载完毕");
    }
}

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
数据加载完毕
数据加载中...
join方法源码

join方法源码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public final synchronized void join(long millis)throws InterruptedException {
	long base = System.currentTimeMillis();
	long now = 0;

	//等待时间小于0直接抛出IllegalArgumentException异常
	if (millis < 0) {
		throw new IllegalArgumentException("timeout value is negative");
	}

	//等待时间为0,调用wait(0),一直等待线程结束。(join(0)等于调用wait(0)等于调用wait())
	if (millis == 0) {
		while (isAlive()) {
			wait(0);
		}
	} else {
		//等待时间大于0时,即使中途被唤醒,只要没超过等待时间,依旧会进入等待状态。
		while (isAlive()) {
			long delay = millis - now;
			if (delay <= 0) {
				break;
			}
			wait(delay);
			now = System.currentTimeMillis() - base;
		}
	}
}

从join方法源码可以看出,join方法的本质是调用线程对象的wait方法,调用join方法时需要获取到线程对象的锁,然后调用线程对象的wait方法,在线程结束后会自动调用线程对象的notifyAll方法

所以当我们在做同步处理时,应该避免使用Thread对象作为锁对象,因为这有可能会影响系统api的工作。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验