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

Java中的多线程详解(超级简单理解)(上篇)

使用工具 IntelliJ IDEA Community Edition 2023.1.4

使用语言 Java8 

代码能力快速提升小方法,看完代码自己敲一遍,十分有用 

目录

1.多线程概述

1.1 进程与线程

1.2 多线程的运行机制

1.3 多线程的优势 

2.多线程编程

2.1 Thread类介绍 

2.2 继承Thread类创建线程类

2.2.1 Thread类贯穿示例 

2.3 实现Runnable接口创建线程类 

2.3.1 Runnable接口贯穿示例

3.线程的状态转换

3.1 状态转换 

3.2 状态转换详解 

3.3 状态转换贯穿示例


1.多线程概述

世间万物中每个个体都可以同时完成很多工作。例如,人体可以同时进行呼吸、血液循环、思考问题等活动。用户既可以使用计算机听歌,也可以编写文档、发送文件等,这些活动可以同时进行。在计算机领域里,这种同时执行多个操作的行为模式被称为并发。在操作系统中同时运行着多个独立的任务,每个任务对应一个进程,每个进程可产生多个线程。通过这种并发运行的方式,计算机的性能被挖掘到了极限。

1.1 进程与线程

进程是程序的一次动态执行过程,它是从代码加载、执行中到执行完毕的一个完整过程,也是进程本身从产生、发展到最终消亡的过程。操作系统同时管理一个计算机系统中的多个进程,让计算机系统中的多个进程轮流使用中央处理器(Central Processing Unit,CPU)资源,或者共享操作系统的其他资源。由于CPU执行速度非常快,所有程序好像是在"同时"运行一样。
操作系统中可以有多个进程,这些进程包括系统进程(由操作系统内部建立的进程)用户进程(由用户程序建立的进程)。可以从Windows任务管理器中查看已启动的进程,进程是系统运行程序的最小单元。各进程之间是独立的,每个进程的内部数据和状态也是完全独立的。
线程是进程中执行运算的最小单位,是在进程基础上的进一步划分,一个线程可以完成一个独立的顺序控制流程。下面看一个简单的问题,假设一个水箱有五个排水孔,打开一个排水孔清空水箱要一个小时,怎样才能使水箱迅速清空并计算最快的清空事件?如果把水箱排水比作一个进程,那么一个排水孔就是一个线程。
与进程不同,同一进程内的多个线程共享同一块内存空间(包括代码空间、数据控件)和一块系统资源,所以系统在产生一个线程或在各线程之间切换工作时,其负担要比在进程间切换小得多。 

综上所述,进程和线程是两个不同的概念。应用程序有单进程单线程的,有多进程但每个进程只有一个线程的,有单进程包含多线程的,还有多进程且每个进程都有多个线程等四种情况。

如果在同一个进程中同时有多个线程,用于执行不同的工作,被称之为"多线程"。这些线程可以同时存在、同时执行。例如,只有一个排水孔的水箱可以比作单线程程序,有多个排水孔的水箱可比作多线程程序。

1.2 多线程的运行机制

以往开发的程序大多是多线程的,即一个程序只有从开始到结束这一条执行路径。而多线程是指一个进程同时存在几条执行路径且并发执行的工作方式。
并发运行与并行运行不同。并行运行通常表示同一个时刻有多条指令代码在处理器上同时运行,这种情况往往需要多个处理器支持。而并发运行表示在一个处理器中,操作系统为了提高程序的运行效率,将CPU的执行时间分成多个时间片,分配给同一进程的不同线程。当执行完一个时间片后,当前运行的线程就可能交付出CPU权限,让其他线程执行下一个时间片,当然CPU也有可能将相邻的时间片分配给同一线程,即多个线程分享CPU时间,交替运行。之所以从表面上看是多个线程同时运行的,是因为不同线程之间切换的时间非常短,也许仅仅是几毫秒,对普通人来说是难以感知的,即所谓的"宏观并行,微观串行" 。

由于进程和线程含义不同,所以运行多个进程和多个线程是不同的。运行多个进程指在同一段时间内,可以同时运行一个以上的程序,即多个任务同时执行。例如,一边浏览网页,一边听音乐。而运行多个线程指在同一个程序内同时运行一个以上的子程序,如使用网盘同时下载多个文件。

1.3 多线程的优势 

多线程作为一种多任务并发的工作方式,有着广泛的应用。合理使用线程,将减少开发和维护的成本,甚至可以改善复杂应用程序的性能。使用多线程的优势如下: 

优势

  • 充分利用CPU的资源。运行单线程程序时,若程序发生阻塞,则CPU可能会处于空闲状态,这将造成计算机资源浪费。而使用多线程可以在某个线程处于休眠或阻塞状态时运行其他线程,这将大大提高资源利用率。
  • 简化编程模型。可以考虑将一个既长又复杂的进程分为多个线程,成为几个独立执行的模块,如使用时、分、秒来描述当前时间。如果时单线程程序,则需要多重判断。如果使用多线程,时,分,秒各使用一个线程控制,每个线程仅需实现简单的流程,简化了程序逻辑,更方便编码和维护。
  • 良好的用户体验。由于有多个线程可以交替运行,减少或避免了程序阻塞或意外情况造成的响应过慢现象,减少了用户等待时间,提升了用户体验。

多线程技术在实际开发中时非常有价值的。例如,Word文本编辑工具需提供一边编辑一边保存的功能,且同时进行规范化格式和标记错别字检查;应该浏览器必须能同时下载多个图片;一个Web服务器必须能同时响应多个用户请求;JVM本身就在后台提供了一个超级线程进行垃圾回收.......总之,多线程在实际编程中的应用是非常广泛的。 

2.多线程编程

Java语言提供了java.lang.Thread类支持多线程编程;

2.1 Thread类介绍 

Thread类提供了大量的方法来控制和操作线程。Thread类的常用方法如下:

Thread()创建Thread对象构造方法
Thread(Runnable target)        创建Thread对象,target为run()方法被调用的对象构造方法
Thread(Runnable target,String name)创建Thread对象,target为run()方法被调用的对象,name为新线程的名字构造方法
void run()执行任务操作的方法实例方法
void start()使该线程开始运行,JVM将调用该线程的run方法
一般使用这个,不直接调用run方法
实例方法
void sleep()在指定的毫秒数内让当前正在运行的线程休眠(暂停运行)静态方法
Thread currentThread()返回当前线程对象的引用静态方法

Thread类的静态方法currentThread()方法返回当前线程对象的引用。在Java程序启动时,一个线程立即随之启动,这个线程通常被称为程序的主线程。public static void main()方法是主线程的入口,每个进程至少有一个主线程。它的重要性如下:

  • 主线程是产生其他子线程的线程
  • 主线程通常必须最后完成运行,因为它执行各种关闭工作 

尽管主线程是自动创建的,但是可以由一个Thread对象控制。因此,可以使用Thread类的方法获取主线程信息。
在Java语言中,实现多线程的方式有两种:一种是继承Thread类,另一种是实现Runnable接口。 

2.2 继承Thread类创建线程类

继承Thread类是实现线程的一种方式。在使用此方法自定义线程类时,必须在格式上满足以下要求:

  • 此类必须继承Thread类
  • 将线程执行的代码写在run()方法中

线程从它的run方法开始执行,即run()方法时线程执行的起点,就像main()方法是应用程序的起点一样。因为run()方法定义在Thread类中,所以在自定义线程类中必须重写run()方法,为线程提供实现具体任务的代码。

2.2.1 Thread类贯穿示例 

示例代码 

 

运行结果 

 

后面的循环内容将会每隔2秒打印一句

注意:
1.已启动的线程对象(就是同一个线程对象)不能重复调用start()方法,否则会抛出IllegalThreadStateException异常。
2.sleep()方法用来控制线程的休眠时间。如果这个线程被其他线程中断,则会产生InterruptedException异常。所以sleep()方法必须进行异常处理。 

线程对象调用start方法和调用run方法截然不同。前者是启动线程,后者是调用实例方法,在实际应用中切不要混淆。

2.3 实现Runnable接口创建线程类 

在使用继承Thread类的方式创建线程的过程中,子类无法再继承其他父类。这是因为Java语言不支持多重继承。在这种情况下,可以通过实现Runnable接口的方式创建线程这种方式更具有灵活性,用户线程还可以通过继承,再具有其他的特性,这是开发中经常使用的方式
Runnable接口位于java.lang包中,其中只提供一个抽象方法run()的声明,Thread类也实现了Runnable接口。使用Runnable接口时也列表框Thread类,这是因为它要用到Thread类中的start()方法。在Runnable接口中只有run()方法,其他操作都要借助于Thread类。使用Runnable接口创建线程的一般格式如下。 

2.3.1 Runnable接口贯穿示例

示例代码 

 

运行结果 

 

后面的循环内容将会每隔2秒打印一句
在以上代码中,虽然TestRunnable类为线程提供了run()方法,但它本身不是线程类。如果创建一个专门执行run()方法的线程对象,则需要创建一个Thread对象。
TestRunnable类实现了Runnable接口,在run()方法中编写线程所执行的代码。如果TestRunnable需要继承其他类,也完全可以实现。 

3.线程的状态转换

3.1 状态转换 

Java语言使用Thread类及其子类的对象表示线程,新建的线程通常会在五种状态中转换,即新建(new)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)。这五种状态组成了线程的生命周期,如下所示: 

3.2 状态转换详解 

新建状态。一个Thread类或其子类的对象被声明并创建,但其还在未启动的这段时间里处于一种特殊的新建状态中。此时,线程类对象已经被分配了内存空间和资源,并且已被初始化,但是该线程尚未被调度;
就绪状态。就绪状态也被称为可运行状态,处于新建状态的线程被启动后,也就是调用start()方法后,新建线程将进入线程队列,排队等待CPU时间片。此时它已具备运行的条件,一旦轮到它使用CPU资源,他就可以脱离创建它的主线程独立开始它的生命周期。这就好比一批作物种子被运输到农场,处于等待果农撒种的状态。
运行状态。当就绪状态的进程被调度并获得处理器资源后便进入运行状态,该状态表示线程正在运行,该线程已经拥有了CPU的占用券。这就好比作物种子被农夫种植到土地里,在阳光的照耀和雨水的浇灌下生根、发芽、茁壮成长。
当调用start()方法后,线程获取资源运行run()方法中的代码,代码进入运行状态。每个Thread类及其子类都拥有一个线程操作方法run(),当线程类对象被调度运行时,它将自动调用此run()方法,从该run()方法的第一条语句开始执行,一直到执行完毕。处于运行状态的线程在以下四种情况下会让出CPU的控制权。

  • 线程运行完毕
  • 有比当前线程优先级更高的线程抢占了CPU
  • 线程休眠
  • 线程因等待某个资源而处于阻塞状态

阻塞状态。一个正在运行的线程在某些特殊情况下需要让出CPU并暂时中止运行。这时,线程处于不可运行的状态被称为阻塞状态。这就好比作物在生长过程中由于干旱少雨或遭遇虫害停滞生长。
导致线程死亡的原因有两个:一时正常运行的线程完成了它的全部工作,即运行完run()方法的最后一条语句并退出;二时当进程停止运行时,该进程中的所有线程将被强行中止。线程处于死亡状态并且没有该线程的引用是,JVM会从内存中删除该线程类对象。 

简而言之,忽略操作系统底层的操作,在程序中可视的线程生命周期是新建线程、start()方法启动线程、调用run()方法运行线程,运行完毕后线程的生命周期就结束了。 

3.3 状态转换贯穿示例

示例代码 

运行结果

相关文章:

Java中的多线程详解(超级简单理解)(上篇)

使用工具 IntelliJ IDEA Community Edition 2023.1.4 使用语言 Java8 代码能力快速提升小方法,看完代码自己敲一遍,十分有用 目录 1.多线程概述 1.1 进程与线程 1.2 多线程的运行机制 1.3 多线程的优势 2.多线程编程 2.1 Thread类介绍 2.2 …...

Elastic-Job 分布式任务调度

一、使用场景 (1)分布式项目中 定时任务。如果只部署一台机器,可用性无法保证,如果定时任务机器宕机,无法故障转移,如果部署多台机器时,同一个任务会执行多次,任务重复执行也会出问…...

YZ系列工具之YZ09: VBA_Excel之读心术

我给VBA下的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套一部VBA手册,教程分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的…...

Python下载音乐

今天我就来分享一下我的方法:Python爬虫 在CS dn社区中我浏览了许多关于爬虫代码,可都有各自的缺陷,有的需要ID比较麻烦,这里我编写了一个程序,他只需要输入歌曲名字即可进行搜索爬取并下载 话不多说,下面的程序复制…...

PCL ICP配准高阶用法——统计每次迭代的配准误差并可视化

目录 一、概述二、代码实现三、可视化代码四、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述 在进行论文写作时,需要做对比实验,来分析改进算法的性能,期间用到了迭代误差分布统计的比较分析,为直…...

电脑卸载软件怎么清理干净?电脑清理的5种方法

随着我们在电脑上安装和卸载各种软件,很多时候我们会发现,即使软件被卸载,其残留的文件和注册表项仍然存在于电脑中,这不仅占用了宝贵的磁盘空间,还可能影响电脑的性能。那么,如何确保在卸载软件时能够彻底…...

LLM流式方案解决方案和客户端解决方案

背景 接上一篇《LLM大模型统一封装接口解决方案》架构确定后,流式方案非常规请求,需要特殊处理。 本解决方案就是针对上一篇中所需要的流式(打字机效果进行编码) 什么是SSE SSE(Server-Sent Events,服务器发…...

ROS2 高效学习系列

ROS2 高效学习系列 1 说明2 正文 1 说明 2023 年,我们总结输出了 ROS高效入门系列 和 ROS高效进阶系列,系统学习了 ros1 基础知识和 ros 的机器人算法。由于 ros2 的普及,我们将系统学习 ros2 ,包括 ros2 基础知识和相关高级组件…...

SpringBoot + MyBatisPlus分页查询

文章目录 1.思路分析2.分页查询后端实现1.com/sun/furn/config/MybatisConfig.java 注入MyBatisPlus分页拦截器2.com/sun/furn/controller/FurnController.java 添加方法3.postman测试 3.分页查询前端实现1.src/views/HomeView.vue 引入分页导航条组件2.src/views/HomeView.vue…...

记使用sjson的一次小事故

1. 前言 之前在设计一个兼容函数的时候,使用了sjson动态设入参数,从而实现一些参数的兼容。大致的逻辑如下所示: // 有一堆不规则的json数据 {"a":"aaa","b":"bbb","any_key1":{"k…...

如何在iOS系统抓取log

前言:因为作者目前工作领域和苹果智能家居有关,然后发现一些bug其实是apple sdk原生code的问题,所以需要给apple提radar单,就需要抓ios端Log充当证据给apple看,其实ios抓log非常简单,大家感兴趣可以学习下哦…...

【嵌入式——QT】Charts常见的图表的绘制

【嵌入式——QT】Charts常见的图表的绘制 柱状图QBarSetQBarSeriesQBarCategoryAxis图示 饼图堆叠柱状图百分比柱状图散点图和光滑曲线图代码示例 柱状图 QBarSet 用于创建柱状图的数据集。 主要函数 setLabel():设置数据集标签 ;setLabelBrush()&am…...

pandas读写excel,csv

1.读excel 1.to_dict() 函数基本语法 DataFrame.to_dict (self, orientdict , into ) --- 官方文档 函数种只需要填写一个参数:orient 即可 ,但对于写入orient的不同,字典的构造方式也不同,官网一共给出了6种&#xff0c…...

清华大学突破性研究:GVGEN技术,7秒内从文字到3D高保真生成

引言:3D模型生成的挑战与机遇 随着计算机图形学的发展,3D模型的生成在各个行业中变得越来越重要,包括视频游戏设计、电影制作以及AR/VR技术等。在3D建模的不同方面中,从文本描述生成3D模型成为一个特别有趣的研究领域,…...

软件测试要学习的基础知识——黑盒测试

概述 黑盒测试也叫功能测试,通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作是一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,对程序接口进行测试,只检查程序功能是否按照需求规格…...

如何用Airtest脚本连接无线Android设备?

之前我们已经详细介绍过如何用AirtestIDE无线连接Android设备,它的关键点在于,需要先 adb connect 一次,才能点击 connect 按钮无线连接上该设备: 但是有很多同学,在使用纯Airtest脚本的形式连接无线设备时&#xff0c…...

c语言函数大全(C开头)

c语言函数大全(C开头) There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should leave quickly. 函数名…...

初始Redis关联和非关联

基础篇Redis 3.初始Redis 3.1.2.关联和非关联 传统数据库的表与表之间往往存在关联,例如外键: 而非关系型数据库不存在关联关系,要维护关系要么靠代码中的业务逻辑,要么靠数据之间的耦合: {id: 1,name: "张三…...

Redis 更新开源许可证 - 不再支持云供应商提供商业化的 Redis

原文:Rowan Trollope - 2024.03.20 未来的 Redis 版本将继续在 RSALv2 和 SSPLv1 双许可证下提供源代码的免费和宽松使用;这些版本将整合先前仅在 Redis Stack 中可用的高级数据类型和处理引擎。 从今天开始,所有未来的 Redis 版本都将以开…...

生产者Producer往BufferQueue中写数据的过程

In normal operation, the producer calls dequeueBuffer() to get an empty buffer, fills it with data, then calls queueBuffer() to make it available to the consumer 代码如下: // XXX: Tests that fork a process to hold the BufferQueue must run bef…...

ubuntu中使用docker

上一篇我已经下载了一个ubuntu:20.04的镜像; 1. 查看所有镜像 sudo docker images 2. 基于本地存在的ubuntu:20.04镜像创建一个容器,容器的名为cppubuntu-1。创建的时候就会启动容器。 sudo docker run -itd --name cppubuntu-1 ubuntu:20.04 结果出…...

matlab 2024a ​工具箱Aerospsce Toolbox报错​

Matlab R2024a中Aerospsce Toolbox报错 警告:Aerospace Toolbox and Aerospace Blockset licenses are required in ‘built-in/Spacecraft Dynamics’ 找到安装路径\MATLAB\R2024a\licenses文件夹license_****_R2024a.lic 里面工具箱名称出错,手动修改…...

婚恋小程序直播系统框架搭建

逻辑分析 直播流管理:需要处理主播端的直播流推送,确保直播流能够稳定、高效地传输到各个观看用户的设备上。这涉及到选择合适的流媒体协议,如 RTMP(Real-Time Messaging Protocol)、HLS(HTTP Live Streami…...

数学建模期末速成 聚类分析与判别分析

聚类分析是在不知道有多少类别的前提下,建立某种规则对样本或变量进行分类。判别分析是已知类别,在已知训练样本的前提下,利用训练样本得到判别函数,然后对未知类别的测试样本判别其类别。 聚类分析 根据样本自身的属性&#xf…...

【基础算法】枚举(普通枚举、二进制枚举)

文章目录 一、普通枚举1. 铺地毯(1) 解题思路(2) 代码实现 2. 回文日期(1) 解题思路思路一:暴力枚举思路二:枚举年份思路三:枚举月日 (2) 代码实现 3. 扫雷(2) 解题思路(2) 代码实现 二、二进制枚举1. 子集(1) 解题思路(2) 代码实现 2. 费解的…...

如何用 pnpm patch 给 element-plus 打补丁修复线上 bug(以 2.4.4 修复 PR#15197 为例)

背景 在实际项目开发中,依赖的三方库(如 element-plus)难免会遇到 bug。有时候官方虽然已经修复,但新版本升级成本高,或者有兼容性风险。这时,给依赖打补丁是最优雅的解决方案之一。 本文以 element-plus…...

学习路之php--性能优化

一、php周边优化 二、代码级优化 变量管理‌ 及时unset()释放大数组/对象,减少内存占用局部变量访问速度比全局变量快约2倍,优先使用局部变量大数组采用引用传递(&$var)避免内存 循环优化‌ 预计算循环次数: …...

《影像引导下骨盆创伤手术的术前骨折复位规划:基于学习的综合流程》|文献速递-深度学习医疗AI最新文献

Title 题目 Preoperative fracture reduction planning for image-guided pelvic trauma surgery: A comprehensive pipeline with learning 《影像引导下骨盆创伤手术的术前骨折复位规划:基于学习的综合流程》 01 文献速递介绍 《影像引导下骨盆创伤手术的术前…...

buuctf——web刷题第二页

[网鼎杯 2018]Fakebook和[SWPU2019]Web1没有,共30题 目录 [BSidesCF 2020]Had a bad day [网鼎杯 2020 朱雀组]phpweb [BJDCTF2020]The mystery of ip [BUUCTF 2018]Online Tool [GXYCTF2019]禁止套娃 [GWCTF 2019]我有一个数据库 [CISCN2019 华北赛区 Day2…...

大语言模型评测体系全解析(下篇):工具链、学术前沿与实战策略

文章目录 一、评测工具链:从手工测试到自动化工程的效率革命(一)OpenCompass:开源评测框架的生态构建1. 技术架构:三层架构实现评测自动化2. 开发者赋能:从入门到进阶的工具矩阵 (二&#xff09…...