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,一经查实,立即删除!

相关文章

【java】【springboot】启动方法注解详解

在Spring Boot中&#xff0c;启动方法通常是main方法&#xff0c;它位于应用程序的主类中&#xff0c;负责启动Spring应用上下文。 一、SpringBootApplication SpringBootApplication 是 Spring Boot 中一个非常核心的注解&#xff0c;它是一个复合注解&#xff0c;包含了三个…

从工艺到性能:模具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; …

香橙派orangepi系统没有apt,也没有apt-get,也没有yum命令,找不到apt、apt-get、yum的Linux系统

以下是一个关于如何在 Orange Pi 上的 Arch Linux 系统中发现缺失包管理器的问题并解决的详细教程。 发现问题 确认系统类型&#xff1a; 使用以下命令检查当前的 Linux 发行版&#xff1a; uname -a cat /etc/os-release如果你看到类似于 “Arch Linux” 的信息&#xff0c;说…

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

顺序表 一.顺序表的原理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作…

使用Java和Spring Retry实现重试机制

使用Java和Spring Retry实现重试机制 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将探讨如何在Java中使用Spring Retry来实现重试机制。重试机制在处理临时性故障和提高系统稳…

Pandas筛选数据的10种方法

Pandas是Python中用于数据操作和分析的强大库之一.它提供了丰富的功能来处理和筛选数据.本文将介绍Pandas中筛选数据的10种常用方法,并通过示例展示具体操作步骤. 1. 基于条件筛选 Pandas支持通过布尔索引根据条件筛选数据.这是最常用的筛选方法之一. import pandas as pd# …

2679. 矩阵中的和

两种方法&#xff1a; 第一种&#xff1a;先对二维列表的每一列进行排序&#xff0c;然后对每一列的数据进行逐个比较&#xff0c;找出最大值。 class Solution:def matrixSum(self, nums: list[list[int]]) -> int:result0mlen(nums)nlen(nums[0])for i in range(m):nums…

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% 以上,支持题目在线…

响应式原理实现(2)vue2和vue3

响应式2 vue2响应式实现 提供shallow&#xff0c;决定是否需要深度响应 /*******************新增 shallow*******************/ export function defineReactive(obj, key, val, shallow) { /****************************************************/const property Object…

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

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

【Nodejs基础06】Node.js常用命令总结

执行JS文件&#xff1a;node xx 初始化package.json: npm init -y&#xff08;所在文件夹不能有中文或特殊符号&#xff09; 下载本地软件包&#xff1a;npm i 软件包名&#xff08;软件包源码全部集成在node_modules文件夹中&#xff09; 下载全局软件包&#xff1a;npm i …

深入理解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.…