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

线程的四种操作

  所属专栏:Java学习     

在这里插入图片描述

 

1. 线程的开启

start和run的区别:

run:描述了线程要执行的任务,也可以称为线程的入口

start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api会在内核中创建线程)

start执行的速度是比较快的,一旦 start 执行完毕,新线程就会开始执行,调用start的线程,main线程也会继续执行

在Java中,一个Thread对象只能对应到一个系统中的线程,在start中就会根据线程的状态来判断,如果Thread对象没有start,此时的状态就是一个new状态,可以顺利调用start,如果已经调用过start,就会进入到其他状态,只要不是new状态,都会抛出异常

2. 线程的终止

当线程B正在运行时,如果发生了特殊情况需要终止掉线程,有两种实现方式:

  1. 通过共享的标记来进行沟通
  2. 调用interrupt()方法来通知

先来看使用自定义的isQuit作为标志位的例子:

public class ThreadDemo4 {private static boolean isQuit = false;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(){@Overridepublic void run() {while (!isQuit){System.out.println("thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread线程终止了");}};thread.start();Thread.sleep(1000);System.out.println("main线程尝试终止thread线程...");isQuit = true;}
}

这时就有一个问题需要注意:

如果isQuit不用static修饰,改为main方法里的局部变量可行不可行?ans:肯定是不可行的

这就涉及到了lambda表达式变量捕获的问题了

变量捕获是lambda表达式/匿名内部类中的一个语法规则:isQuit和lambda表达式定义在一个作用域中,此时lambda内部是可以访问到外部(和lambda同一个作用域)中的变量的,Java中的变量捕获是有一个特殊要求的,要求捕获的变量必须是final或事实final(虽然不是final修饰,但是后面没有更改)

就如上面的代码中,isQuit后面是被修改了的,所以就违反了语法规则

刚开始的形式为什么可以:写在外面就是外部类的成员变量,内部类本来就是可以访问外部类的

再来看interrupted的例子:

Thread类里面有一个boolean类型的成员变量interrupted,初始状态为false,一旦外面有线程调用interrupt方法,就会设置标志位为true

public class ThreadDemo5 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{Thread currentThread = Thread.currentThread();while (!currentThread.isInterrupted()){System.out.println("thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();Thread.sleep(1000);//主线程中控制thread被终止,设置标志位thread.interrupt();}
}

看起来是和自定义的标志位一样的,但是运行之后就会发现出现了异常:

由于在循环中判断和打印的操作太快了,整个循环的时间都是花在sleep方法里的,当main中调用interrupt时,大概率线程thread是在sleep中的,此时Interrupt就不仅能设置标志位,还可以唤醒thread线程,就会抛出InterruptedException异常,catch中捕获到异常也是做了抛出处理,就交给了JVM,程序就异常终止,那么把处理异常的方式更改一下试试:

这时就会发现while循环中的代码一直在执行

这里的原因是当sleep等阻塞函数被唤醒之后,就会清空刚刚设置的标志位,这时interrupted就一直是初始状态,也就导致了死循环,如果需要结束循环,可以把刚刚的异常处理直接改为break。

Java中终止线程的方式:A线程希望B线程能够终止,B线程收到这样的请求之后就可以自行决定是否是立即终止,稍后终止还是直接无视

  1. 如果B线程想要无视A,catch中就什么也不做,B线程就继续执行(sleep清除标志位)
  2. 如果B线程想要立即结束,就在catch中直接break或return
  3. 如果B线程想要稍后再终止,就可以在catch中添加其他的逻辑(释放资源,清理数据,提交结果...),这些完成之后再break/return.

3. 线程的等待

在之前提到过,操作系统针对多个线程的执行是一个“随机执行,抢占式调度”的过程,哪条线程先执行和先结束是不确定的,不过可以通过使用线程等待来决定哪条线程先结束,也就是让最后结束的线程等待先结束的线程,此时后结束的线程就进入了阻塞状态

例如在a线程中调用b.join(),就是让a线程等待b线程先结束,然后a再继续执行

public class ThreadDemo6 {public static void main(String[] args) {Thread thread1 = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread1结束了");});thread1.start();System.out.println("main线程开始等待");try {thread1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("main线程结束等待");}
}

上面的代码是thread1线程先执行,然后main线程开始等待,进入阻塞状态,如果说修改为先让thread1线程结束,main线程再开始等待会如何呢?

此时join并没有发生阻塞,join方法就是确保被等待的线程能够先结束,如果已经结束了,就没有等待的必要了

此外,任何线程都可以等待别的线程,而且可以等待多个线程,或者是多个线程之间互相等待

public class ThreadDemo7 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for(int i = 0;i < 3;i++){System.out.println("线程t1执行...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("线程t1结束");});Thread t2 = new Thread(()->{for(int i = 0;i < 3;i++){System.out.println("线程t2执行...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("线程t2结束");});t1.start();t2.start();System.out.println("main线程开始等待...");t1.join();t2.join();System.out.println("main线程结束等待");}
}

这就是main线程同时等待两个线程的例子,关于两个join的顺序其实没有区别,最终都是等待了4s

在main等待t1和t2同时,t2也可以等待t1:

这样就把原来t1和t2并发执行修改为了t1先执行

main线程也可以被其他线程等待,不过写法不同的是,需要先获取main线程的引用

public class ThreadDemo8 {public static void main(String[] args) throws InterruptedException {Thread mainThread = Thread.currentThread();Thread thread = new Thread(()->{System.out.println("thread等待main线程");try {mainThread.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("结束等待");});thread.start();Thread.sleep(1000);System.out.println("main线程结束");}
}

在上面使用的join方法中,由于是没有传入参数的,就表示被等待的线程只要没有执行完,就会一直等待,这种方式肯定是不好的,如果被等待的线程出现问题了,就会使这个等待操作一直进行,所以就有了传参的版本,但上面列举的第三个高精度的一般也用不到

4. 线程的休眠

之前一直用的Thread.sleep()这个操作就是让调用的线程阻塞等待一定时间的,线程执行sleep之后,就会使这个线程不参与CPU的调度,把CPU的资源让出来,给其他线程使用,在开发时,如果发现某个线程的CPU占用率过高,就可以通过sleep来改善,虽然说线程的优先级也可以影响,但比较有限

在这里插入图片描述

相关文章:

线程的四种操作

所属专栏&#xff1a;Java学习 1. 线程的开启 start和run的区别&#xff1a; run&#xff1a;描述了线程要执行的任务&#xff0c;也可以称为线程的入口 start&#xff1a;调用系统函数&#xff0c;真正的在系统内核中创建线程&#xff08;创建PCB&#xff0c;加入到链…...

自我指导:提升语言模型自我生成指令的能力

人工智能咨询培训老师叶梓 转载标明出处 传统的语言模型&#xff0c;尤其是经过指令微调的大型模型&#xff0c;虽然在零样本&#xff08;zero-shot&#xff09;任务泛化上表现出色&#xff0c;但它们高度依赖于人类编写的指令数据。这些数据往往数量有限、多样性不足&#xf…...

使用Node.js实现单文件上传功能—含代码解释

1、概念 文件上传的具体内容 在前端让用户发送(上传)图片&#xff0c;图片由后端(服务器)接收&#xff0c;并转存到到服务端设备上的操作node.js的文件上传功能主要是使用&#xff1a;multer 插件实现的 搭建一个图片上传的接口 先让接口开通&#xff0c;再去做插件下载/配置等…...

【机器人工具箱Robotics Toolbox开发笔记(一)】Matlab机器人工具箱简介

MATLAB是一款被广泛应用于科学计算和工程领域的专业软件。它的全称为Matrix Laboratory&#xff08;矩阵实验室&#xff09;&#xff0c;因为其最基本的数据类型就是矢量与矩阵&#xff0c;所以在处理数学和科学问题时非常方便&#xff0c;可用于线性代数计算、图形和动态仿真的…...

基于 Metropolis 的朗之万算法

基于 Metropolis 的朗之万算法 1. 未经调整的朗之万算法2. 基于 Metropolis 的朗之万算法 (MALA)2.1. MH算法2.2. 基于 Metropolis 的朗之万算法 (MALA) 3. Metropolis 调整的朗之万截断算法&#xff08;MALTA&#xff09; 1. 未经调整的朗之万算法 未调整的朗之万算法 (ULA) 是…...

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT&#xff0c;这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频&#xff0c;并利用 SAM 2 进行 3D 空间分割&#xff0c;无需进一步训练或 2D-3D 投影。 我们的框架…...

深入理解FastAPI的response_model:自动化数据验证与文档生成

使用 FastAPI 的 response_model 参数 在构建 RESTful API 时&#xff0c;确保数据的一致性和正确性是非常重要的。FastAPI 提供了强大的工具来帮助开发者实现这一目标。其中一个关键特性是 response_model 参数&#xff0c;它允许开发者定义期望的响应格式&#xff0c;并自动…...

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结&#xff0c;删除链表节点问题使用到列表&#xff0c;哈希表&#xff0c;递归比较容易超时&#xff0c;我觉得使用计数排序比较稳&#xff0c;处理起来也不是很难。 1. 力扣3217&#xff1a;从链表中移除在数组中的节点 1.1 题目&#xff1a; 给你一个整数数组 nums 和一…...

快速失败 (fail-fast) 和安全失败 (fail-safe)

1. 定义与工作原理 1.1 快速失败&#xff08;Fail-Fast&#xff09; 定义&#xff1a; 快速失败是一种系统设计原则&#xff0c;当系统遇到异常情况或错误时&#xff0c;立即停止执行并返回错误&#xff0c;而不是试图继续执行或处理潜在的问题。快速失败系统会主动检测系统中…...

【MySQL】MySQL中表的增删改查——(基础篇)(超详解)

前言&#xff1a; &#x1f31f;&#x1f31f;本期讲解关于MySQL中CDUD的基础操作&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;http://t.csdnimg.cn/fNldO &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 目录 …...

【B题第二套完整论文已出】2024数模国赛B题第二套完整论文+可运行代码参考(无偿分享)

2024数模国赛B题完整论文 摘要&#xff1a; 随着电子产品制造业的快速发展&#xff0c;质量控制与成本优化问题成为生产过程中亟待解决的核心挑战。为应对生产环节中的质量不确定性及成本控制需求&#xff0c;本文结合抽样检测理论和成本效益分析&#xff0c;通过构建数学模型…...

大数据之Flink(四)

11、水位线 11.1、水位线概念 一般实时流处理场景中&#xff0c;事件时间基本与处理时间保持同步&#xff0c;可能会略微延迟。 flink中用来衡量事件时间进展的标记就是水位线&#xff08;WaterMark&#xff09;。水位线可以看作一条特殊的数据记录&#xff0c;它是插入到数…...

《Web性能权威指南》-网络技术概览-读书笔记

注&#xff1a;TCP/IP等知识牵涉面太广&#xff0c;且不说本文&#xff0c;哪怕是原书&#xff0c;限于篇幅&#xff0c;很多知识点都是大致介绍下。如果想深入理解&#xff0c;需要更一步Google相关页面资料。 延迟与带宽 WPO&#xff0c;Web Performance Optimization&…...

最新版php进销存系统源码 ERP进销存专业化管理 永久免费升级更新+完整图文搭建教程

在当今信息化时代&#xff0c;企业管理的高效性与精确性是企业竞争力的关键。分享一款最新版的PHP进销存系统源码&#xff0c;一款专为企业设计的ERP进销存管理工具&#xff0c;其丰富的功能、灵活的子账号设置、强大的权限控制、以及独家升级的合同管理和报价单打印功能&#…...

【高效办公】三、两台电脑共享鼠标、键盘和文件,两台电脑当一个用的神操作!barrier

1.下载 ubuntu:sudo apt install barrierwindows:https://github.com/debauchee/barrier/releases-下载 : 2.4.0-Assets-BarrierSetup-2.4.0-release.exe 2.运行 ubuntu:sudo apt install barrierwindows:https://github.com/debauchee/barrier/releases-下载 : 2.4.0-Asset…...

智能合约系统DAPP开发

智能合约系统DAPP&#xff08;去中心化应用&#xff09;的开发是一个复杂且综合性的过程&#xff0c;它结合了区块链技术、智能合约编程、前端开发以及安全性等多方面的知识和技能。以下是对智能合约系统DAPP开发过程的详细概述&#xff1a; 一、需求分析 明确应用场景&#xf…...

宠物狗检测-目标检测数据集(包括VOC格式、YOLO格式)

宠物狗检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1roegkaGAURWUVRR-D7OzzA?pwddxv6 提取码&#xff1a;dxv6 数据集信息介绍&#xff1a; 共有20580 张图像和一一对应的标注文件 标…...

2.5多任务示例编程2

1.CUBEMX配置 2.代码 void StartADC(void const * argument) {/* USER CODE BEGIN StartADC */TickType_t pxPreviousWakeTimexTaskGetTickCount();/* Infinite loop */for(;;){HAL_ADC_Start(&hadc1);if(HAL_ADC_PollForConversion(&hadc1,100)HAL_OK){uint32_t valu…...

JavaWeb - 4 - Vue Ajax

一.Vue Vue Vue是一套前端框架&#xff0c;免除原生JavaScript中的DOM操作&#xff0c;简化书写 基于MVVM&#xff08;Model-VIew-ViewModel&#xff09;思想&#xff0c;实现数据的双向绑定&#xff0c;将编程的关注点放在数据上 官网&#xff1a;https://cn.vuejs.org…...

深入掌握Go语言中的正则表达式与字符串处理

Go语言中的正则表达式与模式匹配 在编程中&#xff0c;字符串处理是常见的需求之一&#xff0c;而正则表达式则是一个强大的工具&#xff0c;能够帮助我们实现复杂的字符串匹配、提取和替换功能。Go语言内置了对正则表达式的支持&#xff0c;通过regexp包&#xff0c;我们可以…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...