多线程(三):线程等待获取线程引用线程休眠线程状态
目录
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状态其实就是就绪状态,分为以下两种:
- 线程正在CPU上执行
- 线程随时可以去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状态。
- sleep指定时间内休眠时
- 处于使用带"超时时间"的阻塞等待时
线程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
相关文章:

多线程(三):线程等待获取线程引用线程休眠线程状态
目录 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的特殊…...

Hi3244 应用指导
Hi3244 是一款DIP8封装高性能、多模式工作的原边控制功率开关。Hi3244内高精度的恒流、恒压控制机制结合完备的保护功能,使其适用于小功率离线式电源应用中。在恒压输出模式中,Hi3244 采用多模式工作方式,即调幅控制(AM࿰…...
【LeetCode热题100】哈希
1.两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答…...
Java的四种循环语句
背景: Java 中主要有四种循环语句:for 循环、while 循环、do-while 循环 和 foreach 循环(也称为增强型 for 循环)。下面我将分别介绍这四种循环语句,并给出相应的实例。 for循环: 1. for 循环for 循环是…...
Qt杂记目录
Qt 杂记目录 QMenu 1.menu转string Qt 窗口阴影边框...
项目开发--基于docker实现模型容器化服务
背景 1、docker-compose build 和 docker-compose up -d分别是什么作用? 2、如何进入新构建的容器当中 3、模型保存的方法区别 4、如何让docker容器启动的时候能使用cuda进行模型推理加速 5、如何实现容器的迭代 解决方案 问题1 docker-compose build 和 docker…...

C语言 | Leetcode C语言题解之第477题汉明距离总和
题目: 题解: int totalHammingDistance(int* nums, int numsSize) {int ans 0;for (int i 0; i < 30; i) {int c 0;for (int j 0; j < numsSize; j) {c (nums[j] >> i) & 1;}ans c * (numsSize - c);}return ans; }...
Bug剖析
Bug剖析 • 所有的Bug报告有以下的基本要求: • 标题。要简略。 • 指派。谁来处理这个问题。 • 重现步骤。问题再次出现的相关步骤。 • 优先级别。问题的紧迫性与重要性。 • 严重程度。问题所产生的后果。 • 解决方案。怎么解决问题。 其他很多方面对修复问题…...

HI3516DV500 相机部分架构初探
Hi3516DV500 是一颗面向视觉行业推出的高清智能 Soc。该芯片最高支持 2 路 sensor 输入,支持最高 5M30fps 的 ISP 图像处理能力,支持 2F WDR、多级降噪、六轴防 抖、多光谱融合等多种传统图像增强和处理算法,支持通过 AI 算法对输入图像进行实…...
训练yolo系列出现问题mAP, R, P等为零
1. 问题 40系列显卡训练yolo系列出现问题,loss正常,但mAP,R,P等为零。 环境:ultralytics版本为8.3.9,cuda11.8, torch2.4。 40系列显卡网上说可以使用cuda低于11.7的,自己测试了下…...

数字媒体技术基础:色度子采样(4:4:4、4:2:2 、4:2:0)
在数字视频处理中,色度子采样 Chroma Subsampling可以用于压缩视频文件的大小,同时在大多数情况下保持较高的视觉质量,它的原理基于人类视觉系统对亮度 Luminance比对色度 Chrominance更加敏感这一特点。 一、 采样格式的表示方法 色度子采样…...

tkinter库的应用小示例:文本编辑器
tkinter库的应用小示例:文本编辑器 要 求: 创建一个文本编辑器,功能包括,创建、打开、编辑、保存文件。一个Button小组件,命名为btn_open,用于打开要编辑的文件,一个Button小组件,命名为btn_s…...
信息抽取数据集处理——RAMS
引言 RAMS数据集(RAMS:Richly Annotated Multilingual Schema-guided Event Structure)由约翰斯霍普金斯大学于2020年发布,是一个以新闻为基础的事件抽取数据集。它标注了9,124个事件,涵盖了139种不同的事件类型和65种…...

SpringBoot+XXL-JOB:高效定时任务管理
前言 在现代应用程序中,定时任务是不可或缺的一部分。Spring Boot 和 XXL-Job 为你提供了一个强大的工具组合,以简化任务调度和管理。 本文将带领你探索如何将这两者集成在一起,实现高效的定时任务管理。无论你是初学者还是有经验的开发者&…...
openpyxl -- 简介
文章目录 介绍核心类 介绍 开源的python读写Excel的工具库,由志愿者在业余时间维护;安装,pip install openpyxl;官方文档地址源码地址issues列表默认openpyxl不能保证抵御大量的xml攻击,为抵御这些攻击需安装defusedxmlÿ…...
滚雪球学MySQL[8.3讲]:数据库中的JSON与全文检索详解:从数据存储到全文索引的高效使用
全文目录: 前言8.3 JSON与全文检索1. JSON数据类型的使用1.1 JSON 数据类型概述1.2 JSON 数据的插入与查询1.3 JSON 常用函数与操作1.4 JSON使用的优缺点与性能考虑 2. 全文索引与全文检索2.1 全文索引概述2.2 全文检索的使用2.3 全文检索模式2.4 全文索引优化与性能…...

position定位静态定位/绝对定位/相对定位
1.静态定位static:按照标准流进行布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>D…...
2024年09月CCF-GESP编程能力等级认证C++编程三级真题解析
本文收录于专栏《C++等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 下列代码中,输出结果是( ) #include<iostream> using namespace std; i...

Web自动化Demo-PHP+Selenium
1.新建工程 打开PhpStorm新建工程如下: 打开终端输入如下命令安装selenium: composer require php-webdriver/webdriver 2.编写代码 <?php require vendor/autoload.php;use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver…...
Python速成笔记——知识(GUI自动化处理屏幕和按键输出)
处理屏幕 获取屏幕快照 函数:pyautogui.screenshot(); 【注】该函数返回包含一个屏幕快照的Image对象; 分析屏幕快照 函数:pyautogui.pixel(); 【注】 传递一个坐标的元组,函数返回坐标对应像素点的RGB值(RGB元组) 函数:pyautogui.pixelMatchesColor() 【注】 函数第一…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...