23.jdk源码阅读之Thread(下)

1. 写在前面

上篇文章我们介绍了Tread的一些方法的底层代码实现,这篇文章我们继续。

2. 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 < 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;}}}/*** Waits at most {@code millis} milliseconds plus* {@code nanos} nanoseconds for this thread to die.** <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** @param  nanos*         {@code 0-999999} additional nanoseconds to wait** @throws  IllegalArgumentException*          if the value of {@code millis} is negative, or the value*          of {@code nanos} is not in the range {@code 0-999999}** @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, int nanos)throws InterruptedException {if (millis < 0) {throw new IllegalArgumentException("timeout value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos >= 500000 || (nanos != 0 && millis == 0)) {millis++;}join(millis);}/*** Waits for this thread to die.** <p> An invocation of this method behaves in exactly the same* way as the invocation** <blockquote>* {@linkplain #join(long) join}{@code (0)}* </blockquote>** @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 void join() throws InterruptedException {join(0);}

这段代码展示了 Java Thread 类中的 join() 方法的几种重载实现。join() 方法的主要功能是让当前线程等待另一个线程的终止。通过调用 join(),当前线程会被阻塞,直到目标线程完成执行。

2.1 join(long millis)

2.1.1 参数

  • millis:等待的时间,以毫秒为单位。值为0表示无限等待。

2.1.2 异常

  • IllegalArgumentException:如果 millis 为负数。
  • InterruptedException:如果当前线程在等待过程中被中断。

2.1.3 实现

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;}}
}
  • 记录当前时间。
  • 检查 millis 是否为负数,如果是,则抛出 IllegalArgumentException。
  • 如果 millis 为 0,当前线程会无限期等待,直到目标线程终止。
  • 否则,当前线程会等待指定的毫秒数,使用 wait() 方法进行等待,并定期检查目标线程是否仍然存活。

2.2 join(long millis, int nanos)

2.2.1 参数

  • millis:等待的时间,以毫秒为单位。
  • nanos:额外等待的时间,以纳秒为单位,范围是 0 到 999999。

2.2.2 异常

  • IllegalArgumentException:如果 millis 为负数,或 nanos 不在 0 到 999999 之间。
  • InterruptedException:如果当前线程在等待过程中被中断。

2.2.3 实现

public final synchronized void join(long millis, int nanos) throws InterruptedException {if (millis < 0) {throw new IllegalArgumentException("timeout value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos >= 500000 || (nanos != 0 && millis == 0)) {millis++;}join(millis);
}
  • 检查 millis 和 nanos 的有效性
  • 如果 nanos 大于等于 500000 或者 nanos 不为 0 且 millis 为 0,则将 millis 增加 1。
  • 调用 join(millis) 方法进行等待。

2.3 join()

调用 join(0) 方法,即无限期等待目标线程终止。

3. interrupt()方法的底层实现

public void interrupt() {if (this != Thread.currentThread())checkAccess();synchronized (blockerLock) {Interruptible b = blocker;if (b != null) {interrupt0();           // Just to set the interrupt flagb.interrupt(this);return;}}interrupt0();}

interrupt() 方法用于中断线程的执行。中断线程的主要目的是通知线程它应该停止当前的工作,并尽快终止。

3.1 中断线程

如果当前线程不是在中断自己(即 this != Thread.currentThread()),则调用 checkAccess() 方法检查权限,可能会抛出 SecurityException。

3.2 线程阻塞的情况

  • 如果线程在调用 Object 类的 wait()、wait(long)、wait(long, int) 方法,或者 Thread 类的 join()、join(long)、join(long, int)、sleep(long)、sleep(long, int) 方法时被阻塞,中断会清除线程的中断状态并抛出 InterruptedException。
  • 如果线程在 I/O 操作中被阻塞(例如在 InterruptibleChannel 上),中断会关闭通道,设置线程的中断状态,并抛出 ClosedByInterruptException。
  • 如果线程在 Selector 上被阻塞,中断会设置线程的中断状态,并立即从选择操作返回,可能返回一个非零值,就像调用了 Selector 的 wakeup 方法一样。
  • 如果以上情况都不适用,则仅设置线程的中断状态。

3.3 中断非活动线程

中断一个不活跃的线程可能没有任何效果。

3.4 同步块

synchronized (blockerLock) {Interruptible b = blocker;if (b != null) {interrupt0();           // Just to set the interrupt flagb.interrupt(this);return;}}
  • 使用 blockerLock 对象进行同步,以确保在检查和修改 blocker 时的线程安全。
  • Interruptible b = blocker;:获取当前线程的 blocker 对象。
  • 如果 blocker 不为 null,调用 interrupt0() 方法设置中断标志,然后调用 blocker 的 interrupt(this) 方法进行中断处理,并返回。

3.5 设置中断标志

如果 blocker 为 null,直接调用 interrupt0() 方法设置中断标志。

3.6 interrupt0()

本地方法,用于设置线程的中断状态。

4. setPriority(int newPriority)

setPriority 方法用于设置线程的优先级。线程的优先级是一个整数值,通常用于调度线程的执行顺序,但具体的调度行为依赖于底层操作系统和 JVM 实现。

4.1 声明变量

ThreadGroup g;

4.2 检查访问权限

checkAccess();

调用 checkAccess() 方法,确保当前线程有权限修改目标线程。如果没有权限,可能会抛出 SecurityException。

4.3 验证优先级范围

if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {throw new IllegalArgumentException();
}

检查 newPriority 是否在合法范围内(即不大于 MAX_PRIORITY 且不小于 MIN_PRIORITY)。如果不在范围内,则抛出 IllegalArgumentException。

4.4 获取线程组

if((g = getThreadGroup()) != null) {

获取当前线程所属的线程组 ThreadGroup。如果线程组不为 null,则继续执行。

4.5 调整优先级

if (newPriority > g.getMaxPriority()) {newPriority = g.getMaxPriority();
}

如果 newPriority 大于线程组的最大优先级 g.getMaxPriority(),则将 newPriority 调整为线程组的最大优先级。

4.6 设置优先级

setPriority0(priority = newPriority);

调用本地方法 setPriority0(int newPriority) 设置线程的优先级,并将 priority 字段更新为 newPriority。

系列文章

1.JDK源码阅读之环境搭建

2.JDK源码阅读之目录介绍

3.jdk源码阅读之ArrayList(上)

4.jdk源码阅读之ArrayList(下)

5.jdk源码阅读之HashMap

6.jdk源码阅读之HashMap(下)

7.jdk源码阅读之ConcurrentHashMap(上)

8.jdk源码阅读之ConcurrentHashMap(下)

9.jdk源码阅读之ThreadLocal

10.jdk源码阅读之ReentrantLock

11.jdk源码阅读之CountDownLatch

12.jdk源码阅读之CyclicBarrier

13.jdk源码阅读之Semaphore

14.jdk源码阅读之线程池(上)

15.jdk源码阅读之线程池(下)

16.jdk源码阅读之ArrayBlockingQueue

17.jdk源码阅读之LinkedBlockingQueue

18.jdk源码阅读之CopyOnWriteArrayList

19.jdk源码阅读之FutureTask

20.jdk源码阅读之CompletableFuture

21.jdk源码阅读之AtomicLong

22.jdk源码阅读之Thread(上)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/50899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从工艺到性能:模具3D打印材料不断革新

在模具3D打印领域&#xff0c;材料性能的持续优化与创新是推动模具3D打印的关键因素&#xff0c;近年来&#xff0c;各种3D打印新材料不断涌现&#xff0c;模具3D打印材料也开始重工艺导向逐步向性能导向发展&#xff0c;如毅速公司推出的ESU-EM191/191S及ESU-EM201不锈钢粉末、…

电脑文件误删除如何恢复?数据恢复第一步是什么?这五点要第一时间处理!

电脑文件误删除如何恢复&#xff1f;数据删除恢复的第一时间要做什么&#xff0c;你知道吗&#xff1f; 在使用电脑的过程中&#xff0c;误删除重要文件的情况时有发生。面对这种情况&#xff0c;不必过于慌张&#xff0c;因为有多种方法可以帮助你恢复误删除的文件。以下是恢复…

网络通信---UDP

前两天做了个mplayer项目&#xff0c;今日继续学习 网络内容十分重要&#xff01;&#xff01;&#xff01; 1.OSI七层模型 应用层:要传输的数据信息&#xff0c;如文件传输&#xff0c;电子邮件等&#xff08;最接近用户&#xff0c;看传输的内容类型到底是什么&#xff09; …

【数据结构与算法】顺序表

顺序表 一.顺序表的原理1.是什么2.数据结构 二.顺序表的初始化三.顺序表增加元素四.顺序表插入元素五.顺序表删除元素六.顺序表的销毁七.总结 一.顺序表的原理 1.是什么 顺序表是一种线性的结构,类似于数组,但是中间不能有空值. 元素顺序地存储在一段连续的内存空间中. 顺序表…

单关节电机动力学辨识

这是一个单关节电机的动力学辨识过程&#xff0c;这是一个yaw轴转动电机的动力学辨识过程 1、动力学建模 &#xff08;1&#xff09;整体动力学 F J α f F J\alpha f FJαf 单关节的物理量包括惯性项、离心力和科氏力、摩擦力。这里忽略离心力和科氏力&#xff0c;据说…

SolidEdge二次开发(C#)-环境配置

文章目录 1、前言2、环境配置2.1 安装Solidworks20242.2 安装VS20222.3 查看Com组件2.3.1 在VS2022中创建一个wpf工程项目2.3.2 添加com组件 1、前言 SolidEdge是Siemens PLM Software公司旗下的三维CAD软件&#xff0c;采用Siemens PLM Software公司自己拥有专利的Parasolid作…

js动画插件-vue

分享一个动画插件 学习 动画插件 是进入大厂的必备技能 首先我们需要先学会 去使用js 动画 封装好的 GreenSock 动画平台 &#xff08;GSAP&#xff09; greensock.com/gsap/ 就是这个插件 我现在分享一个用例 其实很简单 但是 具体的属性 和很多 内容需要慢慢使用 慢慢看…

C++客户端Qt开发——系统相关(文件操作)

2.文件操作 ①输入输出设备类 在Qt中&#xff0c;文件读写的类为QFile。QFile的父类为QFileDevice,QFileDevice提供了文件交互操作的底层功能。QFileDevice的父类是QIODevice,QIODevice的父类为QObject。 QIODevice是Qt中所有输入输出设备(input/output device,简称I/O设备)…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 环形字符串最长子串(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

【React】useState:状态管理的基石

文章目录 一、什么是 useState&#xff1f;二、useState 的基本用法三、useState 的工作原理四、高级用法五、最佳实践 在现代前端开发中&#xff0c;React 是一个非常流行的库&#xff0c;而 useState 是 React 中最重要的 Hook 之一。useState 使得函数组件能够拥有自己的状态…

深入理解synchronized(简记)

深入理解synchronized 管程synchronized对象的内存布局锁状态记录锁对象状态转换偏向锁轻量级锁锁对象转换总结 管程synchronized Java 参考了 MESA 模型&#xff0c;语言内置的管程&#xff08;synchronized&#xff09;对 MESA 模型进行了精简。 对象的内存布局 对象头 Mar…

Nginx笔记(一)

一、Nginx简介 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 [13]&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点&#xff08;俄文&#xff1a;Рамблер&#xff09;开发的&#xff0c;公开版本1.…

如何在宝塔面板给域名配置 SSL 证书

首先需要有证书 这里以阿里云为例 1. 首先进入到 SSL 证书管理控制台 选择个人测试证书&#xff0c;并点击购买 免费的可以使用三个月。 购买完成之后回到控制台。 点击创建证书&#xff0c;将标红的地方填写&#xff0c;其他默认就好。 然后提交审核就行。 这里需要对域名…

【React】组件:全面解析现代前端开发的基石

文章目录 一、什么是组件&#xff1f;二、组件的类型三、组件的生命周期四、状态管理五、属性传递六、组合与继承七、最佳实践 在现代前端开发中&#xff0c;React 已成为开发者构建用户界面的首选框架之一。React 的强大之处在于其组件化设计&#xff0c;允许开发者将 UI 拆分…

Wireshark自定义协议解析器插件C语言开发二

接着上一篇安装文章&#xff0c;在wireshark插件开发完成后&#xff0c;仿真的dll并不能直接分享使用&#xff0c;当另外电脑缺少必要的c环境或依赖项时候&#xff0c;在打开wireshark软件时候即会报错。 上图是仿真得到的dll文件路径&#xff0c;但是并不能在其他没有安装了v…

linux驱动--中断

中断号和中断的申请 中断号的添加-----定义设备节点&#xff0c;描述当前设备 通过设备树文件获取 /dts/xxxx.dts文件中进行设备的设置 在dts设备树文件中进行设备的定义&#xff0c;包括继承的设备&#xff0c;中断号的设置 需要对我们的dts设备树文件进行编译&#xff0…

天机学堂第二天项目 添加我的课表 项目总结

目录 根据产品原型得到数据库表结构 RabbitMq监听 构造器注入 幂等 mybatisplus 分页查询的多种写法 在new page里面添加排序 查询条件中 用orderBydESC指定排序 ​编辑 链式编程中使用page指定排序 stream流 ​编辑 在网关中解析token 根据产品原型得到数据库表结构 根…

基于物联网的区块链算力网络,IGP/BGP协议

目录 基于物联网的区块链算力网络 IGP/BGP协议 IGP(内部网关协议) BGP(边界网关协议) 内部使用ISP的外部使用BGP的原因 一、网络规模和复杂性 二、路由协议的特性 三、满足业务需求 四、结论 基于物联网的区块链算力网络 通 过 多个物联网传感器将本地计算…

使用在UE5中使用AirSim插件Eigen库头文件引用报错,出现报错的解决方式

一、概述 如图所示&#xff0c;用红线圈出的两条头文件引用会报错&#xff0c;提示无法找到他们&#xff0c;但是可以发现的是&#xff0c;他们的路径书写是没有问题的。 // #include <Source/Airlib/deps/eigen3/Eigen/Core> // #include <Source/Airlib/deps/eigen…