join()方法--原理同wait方法

如果不知道保护性暂停是啥的可以参考一下上一篇文章

https://www.cnblogs.com/duizhangz/p/16222854.html

join方法本质上和加了超时的保护性暂停差不多。

首先抛出join方法使用场景即保证线程的顺序执行。

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
t1.join();
log.debug("t1 join结束");
log.debug("继续执行主线程方法");
}

首先我们调用的是t1对象的join()方法,我们首先会知道这个main的主线程会等待t1线程执行结束后才会接着执行。

下面直接抛出源码join()方法,如果join未加参数就是执行join(0)。

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()) { // isAlive 就是判断调用该方法的线程是否存活
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

主要是两个条件判断,一个是当millis参数为0时,就会进入一个wait(0),不为0时就会和上面超时保护差不多的代码中。

首先我们是在main线程中,调用了t1线程对象的join()方法,所以我们需要搞清楚两个状态。

  1. 当前join()方法是synchronized修饰的,所以当前的wait方法锁住的锁资源是t1对象。
  2. 然后main主线程就会因为wait()方法进入waitting状态。直到有人调用了t1.notify方法唤醒了main线程。

这个逻辑比较搞,就这线程那线程的,刚开始我都被搞乱了,仔细想想就OK了。

刚开始学的时候,我就觉得奇怪,t1线程结束是怎么唤醒main线程呢?现在理清楚了就是需要锁资源t1对象调用notifyAll()方法,然而在JVM底层当t1线程运行结束时就会调用该线程对象的notifyAll()方法,将被t1.wait()方法锁住的main线程。

join方法原理的更多相关文章

  1. Java多线程中join方法详解

    join()方法用于让当前执行线程等待join线程执行结束.其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待. join()方法部分实现细节 while(isAli ...

  2. sleep、yield、join方法简介与用法 sleep与wait区别 多线程中篇(十五)

    Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...

  3. 多线程-join()方法

    在很多情况下,主进程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束.这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据 ...

  4. 进程之 Process join方法其他属性与进程Queue

    Process join方法 以及其他属性 在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况 情况一:在主进程的任务与子进程的任务彼此独立的情 ...

  5. 多线程(七)~join方法的使用

    作用:join()方法的作用是等待线程对象销毁.     join()方法具有能使线程排队运行的作用,有点类似于同步的效果.       join与synchronize的区别:         jo ...

  6. 浅析Thread的join() 方法

    Thread中的 join() 方法在实际开发过程中可能用的不是很多,但是在面试中作为考察基本功知识的扎实与否,经常会被用到.因此,对于 Thread 的 join() 方法进行了一定的研究. 常见的 ...

  7. join方法,wait()和sleep()

    join方法解释:方法x.join()的作用是使所属线程x 正常执行run()中的方法,而使得调用x.join()的线程处于无限期阻塞状态,等待x线程销毁后再继续执行线程z后面的代码. 1.方法joi ...

  8. UDP代码编写、操作系统发展史、多道技术、进程理论与代码层面创建、进程join方法与进程对象方法

    昨日内容回顾 socket基本使用 # 内置的模块 import socket s = socket.socket() # 默认是TCP协议 也可以切换为UDP协议 s.bind((ip,port)) ...

  9. mysql join 底层原理

    你知道 Sql 中 left join 的底层原理吗? 2019-09-10阅读 7130 https://cloud.tencent.com/developer/column/2367   01.前 ...

随机推荐

  1. 什么是 Spring 的依赖注入?

    依赖注入,是 IOC 的一个方面,是个通常的概念,它有多种解释.这概念是说你 不用创建对象,而只需要描述它如何被创建.你不在代码里直接组装你的组件和 服务,但是要在配置文件里描述哪些组件需要哪些服务, ...

  2. 学习 Haproxy (五)

    1 Linux Haproxy 负载均衡 v1.8 ★★★ 类似于ningx的反向代理1.1 Haproxy 概述 Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,它支持双机热 ...

  3. 开关电源PCB排版,基本要点分析

    1 开关电源PCB排版基本要点 1.1 电容高频滤波特性 图1是电容器基本结构和高频等效模型. 电容的基本公式是 式(1)显示,减小电容器极板之间的距离(d)和增加极板的截面积(A)将增加电容器的电容 ...

  4. 主线程中的Looper.loop()为什么不会造成ANR

    引子: 正如我们所知,在android中如果主线程中进行耗时操作会引发ANR(Application Not Responding)异常. 造成ANR的原因一般有两种: 当前的事件没有机会得到处理(即 ...

  5. pycharm——import已存在的库居然失败!

    问题 明明在cmd中可以import的库,放到pycharm中却找不到. 问题根源 找了一圈,最后得到这个结论. 因为pycharm默认就是这样的... 解决 打开设置,找到解释器 点击右边齿轮图标, ...

  6. Linux磁盘之inode

    什么是 inode ? 文件储存在硬盘上,硬盘的最小存储单位叫作"扇区"(Sector).每一个扇区储存512字节(至关于0.5KB).操作系统读取硬盘的时候,不会一个个扇区地读取 ...

  7. 『现学现忘』Git基础 — 1、版本控制系统介绍

    在具体了解Git之前,首先需要我们了解一下VCS,即版本控制系统(version control system) 1.什么是版本控制系统 版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版 ...

  8. 帝国CMS批量提取正文内容到简介

    最近接到一个帝国CMS模板改版项目,自带的数据可能是采集的,以前的简介字段内容只截取了60个字,新模板的简介60字符太少了,不美观,想让简介都截取200个字,怎么批量修改呢,文章太多了手动改肯定不行, ...

  9. 【Example】C++ STL 常用容器概述

    前排提醒: 由于 Microsoft Docs 全是机翻.所以本文表格是我人脑补翻+审校. 如果有纰漏.模糊及时评论反馈. 序列式容器 序列容器是指在逻辑上以线性排列方式存储给定类型元素的容器. 这些 ...

  10. 学习HTML第二天

    今日内容: HTML标签:表单标签 CSS HTML标签:表单标签 表单项标签: input:可以通过type属性值,改变元素展示的样式 type属性: text:文本输入框,默认值 placehol ...