当前位置: 首页 > news >正文

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(上)

相关文章:

  • Scala学习笔记20: Future 和Promise
  • 【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十八章 驱动模块编译进内核
  • 【BUG】已解决:The above exception was the direct cause of the following exception:
  • C#知识|账号管理系统:修改登录密码界面的UI设计
  • 一下午连续故障两次,谁把我们接口堵死了?!
  • 【通信模块】LoraWAN网络简介
  • 打造一篇完美的【数学建模竞赛论文】:从准备到撰写的全面指南
  • 免费通配符/泛域名SSL证书快速申请攻略
  • 3.qml与c++模块化开发
  • LeetCode 637, 67, 399
  • go-kratos 学习笔记(7) 服务发现服务间通信grpc调用
  • 文件上传总结
  • TFHE中的数据结构Torus
  • uni-app声生命周期
  • Java小白入门到实战应用教程-循环结构
  • canvas 高仿 Apple Watch 表盘
  • canvas绘制圆角头像
  • CODING 缺陷管理功能正式开始公测
  • Docker容器管理
  • Javascript 原型链
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • mysql 5.6 原生Online DDL解析
  • ubuntu 下nginx安装 并支持https协议
  • ViewService——一种保证客户端与服务端同步的方法
  • v-if和v-for连用出现的问题
  • 安装python包到指定虚拟环境
  • 大型网站性能监测、分析与优化常见问题QA
  • 服务器从安装到部署全过程(二)
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 精彩代码 vue.js
  • 力扣(LeetCode)357
  • 每天一个设计模式之命令模式
  • 七牛云假注销小指南
  • 如何解决微信端直接跳WAP端
  • 微服务框架lagom
  • 微信小程序实战练习(仿五洲到家微信版)
  • 微信支付JSAPI,实测!终极方案
  • 小李飞刀:SQL题目刷起来!
  • 字符串匹配基础上
  • 交换综合实验一
  • ​VRRP 虚拟路由冗余协议(华为)
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • # 职场生活之道:善于团结
  • #mysql 8.0 踩坑日记
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (02)Unity使用在线AI大模型(调用Python)
  • (13)DroneCAN 适配器节点(一)
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (二)windows配置JDK环境
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (黑马C++)L06 重载与继承
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐