多线程(三):线程等待获取线程引用线程休眠线程状态

目录

1、等待一个线程:join

1.1 join()

1.2 join(long millis)——"超时时间"

 1.3 join(long millis,int nanos)

2、获取当前线程的引用:currentThread

3、休眠当前进程:sleep

3.1 实际休眠时间

3.2 sleep的特殊写法——sleep(0)

4、线程状态

4.1 NEW

4.2 TERMINATED

 4.3 RUNNABLE

4.4 TIMED_WAITING 

4.5 WAITING


1、等待一个线程:join

1.1 join()

在并发中,我们通常用这样一个需求,一个线程执行完后,另一个线程才能终止,也就是需要控制两个线程结束的先后顺序。

我们可以通过上篇博客所提到的sleep来设置线程的休眠时间,从而控制线程的结束的先后顺序,但是这样的做法是不科学的。比如,我们需要在t线程结束后,让main线程紧跟着结束,此时sleep就显得不靠谱了~~

我们就可以通过:

  • 在main线程中调用t.join()方法,来让main线程等待 t 线程结束后,main再结束。
  • 当代码执行到t.join时,main线程就会发生"阻塞等待",等待t线程结束后,join再继续执行。

join方法也会抛出InterruptedException异常。 

注意:在哪个线程中调用join,就是哪个线程在"阻塞等待"。

1.2 join(long millis)——"超时时间"

其实上文的join是不科学的"等待",其实就是不见不散的“死等”,要是另t线程一直没有结束,main线程就会一直等待下去。

join还提供了另外一个版本,带参数的join(long millis),带有“超时时间”的等待,“超时时间”即最大的等待时间,当等待的时间超过设定的“超时时间”后,main就不会继续等待下去了,继续执行join下面的代码。

例如:在main线程中调用t.join(3000):

  • 当main等待的时间超过3秒后,t线程还没有结束,main就不会继续等待,继续行join下面的代码。
  • 当main等待的时间还没有超过3秒时,即在3秒之内t已经执行完了(t提前结束),此时main也不会再等待了,也会继续行join下面的代码。

带有超时时间的等待,才是更科学的等待(当电脑或者手机程序卡死的时候,就会弹出等待时间的窗口)。尤其是在和网络通信相关的领域都是需要设置"超时时间"。

public class Demo10 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {Thread.currentThread();for(int i = 0; i < 3000; i++) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t 线程终止");});t.start();// main 等待 t//t.join();//main 最多等待 t 3秒//t.join(3000);t.join(3000,500);System.out.println("main 终止");}
}

 1.3 join(long millis,int nanos)

join(long millis,int nanos),nanos即纳秒,即"超时时间"精确到纳秒级别,是更为精确的等待。对于我们开发来说,几乎不会使用。

1s = 1000ms(毫秒),1ms = 1000us(微秒),1us = 1000ns(纳秒)

在计算机中,很难做到ns级别的精确测量,即使线程的调度也是ms级别的开销。

但是也并非做不到,"实时操作系统"就可以做到更为精确的时间计算,我们平常接触到的Windows、Linux、Mac、Android系统都不是实时操作系统,这类操作系统常用于航天、军事、工业领域。实时操作系统,其实时性非常高,但是也是在削弱很多功能下达到的,俗话说得好,鱼和熊掌不可兼得~~


2、获取当前线程的引用:currentThread

这个方法我们已经很熟悉了,上篇博客已经为大家进行了讲解。

我们只需要记住一点:在哪个线程中调用,获取的就是哪个线程的引用(类似于this)。


3、休眠当前进程:sleep

3.1 实际休眠时间

这个方法我们也是很熟悉的了。

但是要额外注意一点:实际的休眠时间,往往是要大于我们所设置的休眠时间的。

使用sleep方法让线程休眠时,实际是让当前线程让出CPU资源,当休眠时间一到,只能说明当前线程是允许被操作系统调度到CPU上执行了,而并不是说明是立即被执行。

也就是说还会有一些线程被调度的时间的开销,一般是ms级别的开销。

3.2 sleep的特殊写法——sleep(0)

sleep(0)是使用sleep的一种特殊写法。意味着让当前线程立即放弃CPU资源,让给其他线程,再等待操作系统重新调度。

当一个模块CPU占有率比较高,影响到其他模块正常执行时,就可以通过这种方式来缓解资源紧张。


 到目前为止,基于对Thread类的学习,我们已经掌握了:

  • 创建线程
  • 关键属性
  • 终止线程
  • 线程等待
  • 获取线程引用
  • 线程休眠

接下来,我们再谈线程状态~ 


4、线程状态

我们知道 进程 分为以下两种状态:

  • 就绪
  • 阻塞

但是这两种状态都是站在操作系统的视角所定义的,在Java线程中,Java也是对操作系统线程进行了封装,对于线程状态也是重新进行表示。

  • NEW: 安排了工作, 还未开始行动
  • TERMINATED: 工作完成了
  • RUNNABLE: 可工作的。又可以分成正在工作中和即将开始工作
  • TIMED_WAITING: 这几个都表示排队等着其他事情
  • WAITING: 这几个都表示排队等着其他事情
  • BLOCKED: 这几个都表示排队等着其他事情

4.1 NEW

NEW状态是指:仅仅new好了Thread对象,但是还没有创建线程(还没有start)。

public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {System.out.println("hello t");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});// NEW 状态System.out.println(t.getState());}

4.2 TERMINATED

TERMINATED状态是指:线程已经结束,但是Thread对象依旧存活。即:线程执行完毕。

public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {System.out.println("hello t");});t.start();Thread.sleep(1000);// 此时 t 线程已结束// TERMINATEDSystem.out.println(t.getState());}

 4.3 RUNNABLE

 RUNNABLE状态其实就是就绪状态,分为以下两种:

  1. 线程正在CPU上执行
  2. 线程随时可以去CPU上执行

RUNNABLE是处于NEW和TERMINATED之间的状态。 

public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {}});t.start();// t 线程正在执行// RUNNABLESystem.out.println(t.getState());}

4.4 TIMED_WAITING 

TIMED_WAITING状态是一种阻塞状态(不参与CPU调度,不继续执行了),但是是有指定时间的阻塞,阻塞的时间有上限。

当线程处于以下状态时就为TIMED_WAITING状态。

  1. sleep指定时间内休眠时
  2. 处于使用带"超时时间"的阻塞等待时

线程sleep前为RUNNABLE状态,sleep时为TERMINATED状态,sleep后又回到RUNNABLE状态。

public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (true) {try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();// TIMED_WAITINGThread.sleep(1000);System.out.println(t.getState());}

4.5 WAITING

WAITING也是一种阻塞状态,只不过是死等,即没有"超时时间"的阻塞等待。

public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (true){}});t.start();// 没有超时时间的阻塞等待t.join();// 此时main线程就处于 WAITING状态}

END

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

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

相关文章

电脑查不到IP地址是什么原因?怎么解决

在日常使用电脑的过程中&#xff0c;有时会遇到无法查询到电脑IP地址的情况&#xff0c;这可能会影响到网络的正常使用。本文将探讨电脑查不到IP地址的可能原因&#xff0c;并提供相应的解决方案。 一、原因分析 ‌网络连接问题‌&#xff1a;首先&#xff0c;网络连接不稳定或…

大数据-159 Apache Kylin 构建Cube 准备和测试数据

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

QD1-P26、27、28 CSS 属性 文本

本节&#xff08;P26、27、28 三合一&#xff09;学习&#xff1a;CSS 文本属性。 ‍ 本节视频 https://www.bilibili.com/video/BV1n64y1U7oj?p26 CSS&#xff08;层叠样式表&#xff09;中用于设置文本样式的属性有很多&#xff0c;以下是一些常用的文本属性&#xff1a; …

机器视觉AI场景为什么用Python比C++多?

好多开发者在讨论机在机器视觉人工智能领域的时候&#xff0c;纠结到底是用Python还是C&#xff0c;实际上&#xff0c;Python 和 C 都有广泛的应用&#xff0c;选择 Python而不是 C 可能有以下一些原因&#xff1a; 语言易学性和开发效率 语法简洁&#xff1a; Python 语法简…

Windows 安装Redis(图文详解)

Windows 安装Redis&#xff08;图文详解&#xff09; Redis是什么数据库&#xff1f; Remote Dictionary Server(Redis) 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库&#xff0c;并提供多种语…

【exceljs】纯前端如何实现Excel导出下载和上传解析?

前段时间写过一篇类似的文章&#xff0c;介绍了sheetjs。最近发现了一个更好用的库ExcelJS&#xff0c;它支持高级的样式自定义&#xff0c;并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式&#xff0c;不过需要使用付费版。 下面对比了Exceljs和Sheetjs&#xff1a…

SQLI LABS | SQLI LABS 靶场初识

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;SQLI LABS 靶场简介 SQLi-Labs 靶场是一个专门用于学习和测试 SQL 注入漏洞的开源靶场&#xff0c;该靶场提供了多个具有不同漏洞类型和难度级别的 Web 应用程序的环境。这些应用…

LabVIEW开关磁阻电机特性测量系统

基于LabVIEW软件和特定硬件组件的开关磁阻电机&#xff08;SRM&#xff09;特性测量系统&#xff0c;结合多功能数据采集卡&#xff0c;统能够准确地测量并分析SRM的电磁特性&#xff0c;从而支持电机模型的精确建立和性能优化。 项目背景 在工业生产和家用电器领域&#xff0…

树莓派应用--AI项目实战篇来啦-15.SSD Mobilenet V3目标检测

1. Mobilenet 介绍 Mobilenet 是一种专为移动和嵌入式视觉应用而设计的卷积神经网络。它们不使用标准的卷积层&#xff0c;而是基于使用深度可分离卷积的简化架构&#xff0c;使用这种架构&#xff0c;我们可以为移动和嵌入式设备&#xff08;例如&#xff1a;树莓派&#xff0…

chattts一步步的记录,先跑起来。

0.下载git工具 Git - Downloads (git-scm.com)https://git-scm.com/downloads Download – TortoiseGit – Windows Shell Interface to Githttps://tortoisegit.org/download/ 1.安装 随意&#xff0c;可以安汉化&#xff0c;也可不安。无所谓 2.建个目录&#xff0c;我的上…

tkinter库的应用小示例:文本编辑器

tkinter库的应用小示例&#xff1a;文本编辑器 要 求&#xff1a; 创建一个文本编辑器&#xff0c;功能包括&#xff0c;创建、打开、编辑、保存文件。一个Button小组件&#xff0c;命名为btn_open,用于打开要编辑的文件&#xff0c;一个Button小组件&#xff0c;命名为btn_s…

Mysql(3)—数据库相关概念及工作原理

一、数据库相关概念 ​ 数据库&#xff08;Database, DB&#xff09; &#xff1a; 数据库是一个以某种有组织的方式存储的数据集合。它通常包括一个或多个不同的主题领域或用途的数据表。 数据库管理系统&#xff08;Database Management System, DBMS&#xff09; &#xf…

【AIGC】ChatGPT提示词Prompt高效编写模式:结构化Prompt、提示词生成器与单样本/少样本提示

&#x1f4af;前言 在如今AI技术迅猛发展的背景下&#xff0c;尽管像ChatGPT这样的大型语言模型具备强大的生成能力&#xff0c;但它们的输出质量有时仍难以完全满足我们的预期。为了让ChatGPT生成更加准确、可靠的内容&#xff0c;掌握高效的Prompt编写技巧变得尤为重要。本文…

Rust 与生成式 AI:从语言选择到开发工具的演进

在现代软件开发领域&#xff0c;Rust 语言正在逐步崭露头角&#xff0c;尤其是在高性能和可靠性要求较高的应用场景。与此同时&#xff0c;生成式 AI 的崛起正在重新塑造开发者的工作方式&#xff0c;从代码生成到智能调试&#xff0c;生成式 AI 的应用正成为提升开发效率和质量…

【论文阅读笔记】Bigtable: A Distributed Storage System for Structured Data

文章目录 1 简介2 数据模型2.1 行2.2 列族2.3 时间戳 3 API4 基础构建4.1 GFS4.2 SSTable4.3 Chubby 5 实现5.1 Tablet 位置5.2 Tablet 分配5.3 为 tablet 提供服务5.4 压缩5.4.1 小压缩5.4.2 主压缩 6 优化6.1 局部性组6.2 压缩6.3 缓存6.4 布隆过滤器6.5 Commit日志实现6.6 T…

【OpenCV】(三)—— 截取图片内容

ROI&#xff0c;全称为region of interest&#xff0c;意为感兴趣的区域&#xff0c;通常为图像中需要特别关注或处理的部分。ROI技术常用于图像分析、目标检测、特征提取等场景&#xff0c;能够帮助减少计算量、提高处理速度和精度。 切片获取ROI图像 我们之前介绍过使用ope…

STM32传感器模块编程实践(四)舵机+MPU6050陀螺仪模块融合云台模型

文章目录 一.概要二.实验模型原理1.硬件连接原理框图2.控制原理 三.实验模型控制流程四.云台模型程序五.实验效果视频六.小结 一.概要 云台主要用来固定摄像头。准确地说&#xff0c;云台是一种可以多角度调节的支撑设备&#xff0c;类似于人的脖子可以支撑着脑袋&#xff0c;…

Java_ EE (网络编程)

网络编程基本概念: 计算机网络计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计算机系统。从其…

利用弹性盒子完成移动端布局(第二次实验作业)

需要实现的效果如下&#xff1a; 下面是首先是这个项目的框架&#xff1a; 然后是html页面的代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…

springboot系列--web相关知识探索五

一、前言 web相关知识探索四中研究了请求中所带的参数是如何映射到接口参数中的&#xff0c;也即请求参数如何与接口参数绑定。主要有四种、分别是注解方式、Servlet API方式、复杂参数、以及自定义对象参数。web相关知识探索四中主要研究了复杂参数底层绑定原理。本次主要是研…