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

【JavaEE】初识线程


一、简述进程

认识线程之前我们应该去学习一下“进程" 的概念,我们可以把一个运行起来的程序称之为进程,进程的调度,进程的管理是由我们的操作系统来管理的,创建一个进程,操作系统会为每一个进程创建一个 PCB,并为进程在内存中开辟一块运行空间 ,然后把这个 PCB 加入到链表中。

进程的调度是为了解决,处理多进程运行的机制,CPU 按照并发的方式执行进程,在进程之间高速切换,看起来就是多进程同时运行。为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录性数据结构。它是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,PCB 记载了进程的优先级,进程的状态,进程的上下文,进程的记账信息等等。

进程的概念就是为了能够实现,多任务,并发执行(”同时执行“)的机制。

能否实现多进程并发执行,需要看操作系统是否能够支持操作,执行的效率这个是考验CPU 的性能。

想要学习更多进程知识的朋友可以观看博主的上一篇博客——【JavaEE】浅识进程_保护小周ღ的博客


二、什么是线程

进程是操作系统分配资源的基本单位,无论是创建,还是调度都是非常麻烦的,进程与进程之间的独立性是较高的,多进程协同维护同一个程序,对资源的消耗是非常大的。

举个例子:我们的QQ 当我们与别人打qq电话的时候,还可以接收qq 消息,并且qq空间同一时刻也接收了你铁哥们发的动态,做个假设,这三个功能是不是可以看作是三个进程,他们可以相互独立的运行,不受其他进程的影响,进程之间又有着某种关联,可以相互通信,他们共同维护了 qq 这个应用。

那么这个假设的例子:我们运行qq , 操作系统此时要给三个进程分配系统资源,开辟内存空间,而且还要花费精力保证进程之间的通信、关联性,是不是很复杂~此时的复杂主要体现在系统资源的分配上。


2.1 线程的概念

线程是建立在进程的基础之上的,可以看作是轻量级的进程,一个进程可以包含一个或者多个线程,同一个进程下的线程之间都是独立且可以调度执行的“执行流”,也是并发执行的,这些线程之间共用父进程的系统资源。

举个例子:


根据以上实例:

  1. 线程是建立在进程的基础上的,进程包含线程

  1. 同一个进程内部,多个线程之间,共用一份系统提供给进程的资源(内存空间,资源共享)

  1. 启动进程后(一般是会创建一个线程,例如 JAVA ,C/C++ 中的main() 函数,程序从main()函数开始执行,操作系统为main() 函数开辟栈帧,然后CPU 的寄存器处理、维护栈帧),需要系统花时间,花精力去分配系统资源,进程创建完毕后,无论当中有多少个线程,站在进程的角度上都不需要再去申请系统资源了,线程之间共用一份进程资源。

  1. 进程是系统分配资源的基本单位。

  1. 操作系统真正调度的是线程,线程是操作系统调度运行的基本单位。

  1. 进程之间相互独立,同一个进程之下,线程之间共享进程资源,此时如果其中一个线程崩溃有可能会对其他线程造成影响,甚至是崩溃。

  1. 一个进程中的线程数应当设计合理,线程之间也是并发执行,而CPU 的核心处理器是有限的,如果同一个进程下的线程过多,虽然在系统资源的分配上只需要执行一次,但是 CPU 需要并发处理的数量过多的话,反而会使得线程的执行的效率变低(CPU高速来回切换的处理线程)。

上文博主假设的qq 例子,应该是一个进程,然后不同的功能交由多线程来执行,功能之间可以独立并发执行,共同维护我们的qq。


三、 Java创建线程

Java 学习过程中主要是偏向于多线程开发,那么接下来学习的是如何用Java 代码来创建一个线程。

3.1 继承Thread 类

Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装.

API : Application Programing linerface

给你一个软件,你能对他干什么,基于它提供的这些功能,就可以写一些代码,然后封装在一起,方便别人使用。

举个例子:

张三肚子饿了,想吃猪脚饭,自己做吧,首先得买猪脚,买调料,洗猪脚,切割,起锅烧油……想想都麻烦,于是张三打消了自己做饭的念头,于是前往楼下小吃店购买猪脚饭,张三到店之后,老板娘给张三一张纸,让他写一写自己想吃啥。

什么意思?我们想吃猪脚饭,不需要知道猪脚饭是怎么做的,我们只需要知道哪里有卖猪脚饭得地方即可

我们想创建一个线程,首先得找到 ”饭店“,这个饭店就是操作系统对创造线程操作封装的API ,然后JAVA 把 操作系统提供的 API 进一步的处理,封装成 Thread 类,我们不需要知道 系统是怎么创建一个线程的,只需要知道 Thread 类,可以吃到 "猪脚饭”。

代码实现:

class MyThread extends Thread {// MyThread 类继承 Thread 类,创建一个线程类// 并重写 Thread 类的 run() 方法// 此时MyThread 线程类的 run() 方法相当于 主线程中的 main() 方法@Overridepublic void run() {while (true) {try {Thread.sleep(1000); //线程休眠,1000 = 1 秒System.out.println("t 线程 执行");} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Demo1 {public static void main(String[] args) {// 创建 MyThread 线程类实例化对象Thread t = new MyThread();// start 创建是新的线程并启动执行,调用run() 方法// 创建线程默认就会执行线程的 run 方法// 不调用 start() 方法线程不会启动t.start();while (true) {try {Thread.sleep(1000); //线程休眠,1000 = 1 秒System.out.println("Main主线程 执行");} catch (InterruptedException e) {e.printStackTrace();}}}
}

线程不调用 start() 方法线程不会启动

调用start() 方法会从系统中创建一个线程,新的线程会执行 run 方法,run 方法式线程的入口方法,类型于主线程的 main() 方法。

启动线程之后,线程就会进入就绪状态,随时准备被系统调度,CPU 执行。

两个线程中分别设置了死循环,打印线程执行,可以出看出控制台两个线程都可以打印数据,也就是说两个线程之间宏观上是并发执行的,线程执行的顺序是无序的。

MyThread 线程类的 run() 方法相当于 主线程中的 main() 方法,都是描述线程的入口。

疑问点:为什么调用 start() 方法会自动执行 run() 方法?

因为类Thread中的start方法中,调用了Thread中的run方法。
MyThread继承了Tread类,在MyThread 中重写run方法,就会覆盖掉Thread中的run方法,子类重写父类方法,优先调用子类重写后的方法,如果子类没有重写父类方法,默认执行的是父类的 run 方法,所以子类调用start方法后,实现的是自己的run方法体里面的代码。

3.2 实现 Runnable 接口

  1. 自定义一个类使其实现 Runnable 接口

class MyThread2 implements Runnable { //实现 Runnable 接口@Overridepublic void run() { //重写接口里面的 run 方法//线程运行的代码while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程t执行");}}
}
  1. 创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数.

public class Demo2 {public static void main(String[] args) {//创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数.Thread t = new Thread(new MyThread2());t.start();// 启动线程while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("主线程 main 执行");}}
}

这是 Thread 线程类提供的有参构造方法,可以看出里面是 Runnable 接口的引用来接收,我们自定义的线程类由于实现了 Runnable 接口,此时发生向上转型,父接口引用接收子类对象,由于子类重写了 Runnable 接口的 run 方法,所以接口引用可以直接调用子类重写后的 run 方法,如果在 父类想调用子类其他独有的成员变量或者是方法,就需要 向下转型(强制类型转换)。

然后线程对象 t 调用 start() 方法启动线程然后调用 run() 方法。

采用实现接口方式创建一个线程 与 继承 Threard 类 创建一个线程 最终的结果是没什么区别的。


3.3 lambda 表达式创建线程

Thread t = new Thread(() -> {System.out.println("使用匿名类创建 Thread 子类对象");
});t.start();

我们常常在通过创建 Thread 对象的时候,通过创建匿名内部类重写 run() 方法。

这里创建的匿名内部类

lambda 表达式的本质就匿名函数。

语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。

有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以利用 lambda表达式的接口快速指向一个已经被实现的方法。

public class Demo3 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread( () -> {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程 T执行");}});t.start(); //启动while (true) {Thread.sleep(1000);System.out.println("主线程Main执行");}}
}

至此,进程的基本认识博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。

本期收录于博主的专栏——JavaEE,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“JavaEE基础知识”。

下期预告:Thread 类 以及 常见方法

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘

相关文章:

【JavaEE】初识线程

一、简述进程认识线程之前我们应该去学习一下“进程" 的概念,我们可以把一个运行起来的程序称之为进程,进程的调度,进程的管理是由我们的操作系统来管理的,创建一个进程,操作系统会为每一个进程创建一个 PCB&…...

智慧水务监控系统-智慧水务信息化平台建设

平台概述柳林智慧水务监控系统(智慧水务信息化平台)是以物联感知技术、大数据、智能控制、云计算、人工智能、数字孪生、AI算法、虚拟现实技术为核心,以监测仪表、通讯网络、数据库系统、数据中台、模型软件、前台展示、智慧运维等产品体系为…...

【Linux】进程优先级前后台理解

环境:centos7.6,腾讯云服务器Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹相关文章推荐:【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习(Ⅰ)浅谈Linux下的shell--BASH【Linux…...

时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元)

时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元) 目录 时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元)效果一览基本描述模型描述程序设计参考资料效果一览...

python 模拟鼠标,键盘点击

信息爆炸 消息轰炸模拟鼠标和键盘敲击import time from pynput.keyboard import Controller as key_col from pynput.mouse import Button,Controller def keyboard_input(insertword):keyboardkey_col()keyboard.type(insertword)def mouth():mouseController()mouse.press(…...

【CSS】盒子边框 ③ ( 设置表格细线边框 | 合并相邻边框 border-collapse: collapse; )

文章目录一、设置表格细线边框1、表格示例2、合并相邻边框3、完整代码示例一、设置表格细线边框 1、表格示例 给定一个 HTML 结构中的表格 , 默认样式如下 : <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8" />…...

TensorRT量化工具pytorch_quantization代码解析(一)

量化工具箱pytorch_quantization 通过提供一个方便的 PyTorch 库来补充 TensorRT &#xff0c;该库有助于生成可优化的 QAT 模型。该工具包提供了一个 API 来自动或手动为 QAT 或 PTQ 准备模型。 API 的核心是 TensorQuantizer 模块&#xff0c;它可以量化、伪量化或收集张量的…...

【Kubernetes】第二十七篇 - 布署前端项(下)

一&#xff0c;前言 上一篇&#xff0c;介绍了前端项目的部署&#xff1a;项目的创建和 jenkins 配置&#xff1b; 本篇&#xff0c;创建 Deployment、Service&#xff0c;完成前端项目的部署&#xff1b; 二&#xff0c;创建 Deployment 创建 Deployment 配置文件&#xff…...

【MFC】两个ListBox控件数据交互

一.控件ID名称 界面如图下所示&#xff1a; 候选数据列表的ID为&#xff1a; 已选数据列表的ID为&#xff1a; 二.数据添加 可以使用以下代码往框中添加数据&#xff1a; ((CListBox *)GetDlgItem(IDC_LIST_TO_CHO))->AddString("测试数据"); 显示效果如下&#…...

sklearn库学习--SelectKBest 、f_regression

目录 一、SelectKBest 介绍、代码使用 介绍&#xff1a; 代码使用&#xff1a; 二、评分函数 【1】f_regression&#xff1a; &#xff08;1&#xff09;介绍&#xff1a; &#xff08;2&#xff09;F值和相关系数 【2】除了f_regression函数&#xff0c;还有一些适用于…...

蓝桥杯刷题第十三天

第一题&#xff1a;特殊日期问题描述对于一个日期&#xff0c;我们可以计算出年份的各个数位上的数字之和&#xff0c;也可以分别计算月和日的各位数字之和。请问从 1900 年 11 月 1 日至 9999 年 12 月 31 日&#xff0c;总共有多少天&#xff0c;年份的数位数字之和等于月的数…...

CPU 和带宽之间的时空权衡

在 从一道面试题看 TCP 的吞吐极限 一文的开始&#xff0c;我提到在环形域上两个数字比较大小的前提是在同一个半圆内&#xff0c;进而得到滑动窗口最大值被限定在一个环形域的一半。 现在来看更为基本的问题。如果序列号只有 2bit&#xff0c;甚至仅有 1bit&#xff0c;保序传…...

ES+Redis+MySQL,这个高可用架构设计太顶了!

一、背景 会员系统是一种基础系统&#xff0c;跟公司所有业务线的下单主流程密切相关。如果会员系统出故障&#xff0c;会导致用户无法下单&#xff0c;影响范围是全公司所有业务线。所以&#xff0c;会员系统必须保证高性能、高可用&#xff0c;提供稳定、高效的基础服务。 …...

【Maven】Maven的常用命令

目录 一、Maven的常用命令 1、compile 编译命令 2、test 测试命令 3 、clean 清理命令 4、package 打包命令 5、 install 安装命令 6、Maven 指令的生命周期 二、maven 的概念模型 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一…...

python的循环结构

python中有for循环和while循环两种形式。 1. for 循环 可以用for循环来遍历不同类型的对象&#xff0c;如数组、列表、元组、字典、集合或字符串&#xff0c;并对每个元素执行一段代码。 1.1 数组的for循环 用for循环遍历一个数组&#xff0c;并打印出每个元素&#xff1a;…...

五种Python中字典的高级用法

1. 引言 Python中的字典是一种非常有用的数据结构&#xff0c;它允许大家存储键值对。通常来说&#xff0c;字典灵活、高效且易于使用&#xff0c;是Python中最常用的数据结构之一。字典通常被用于统计频率、映射值等任务&#xff0c;但在Python中使用字典也可以达到许多意想不…...

[蓝桥杯单片机]——八到十一届初赛决赛客观题

第八届初赛 一、填空题 采用外部12MHz晶振&#xff0c;经过系统12分频时定时器获得最大定时长度&#xff0c;此时定时器定时脉冲为1MHz&#xff0c;周期为1s&#xff0c;而定时器计时均为16位加法计数器&#xff0c;即计时长度为。 二、 选择题 ①带阻滤波器是指能通过大多数频…...

多线程(初阶)

文章目录一.初始线程(Thread)1.1.线程的概念1.2.线程的优势1.2.1.线程比进程更轻量1.2.2.并发编程1.3.线程和进程的区别二.Thread类方法2.1. java 中创建线程的方法2.1.1. 继承Thread,重写run2.1.2. 实现Ruuable接口2.1.3. 使用匿名内部类,继承Thread2.1.4.使用匿名内部类,实现…...

【Vue从入门到进阶】Node.js安装与配置

✅作者简介&#xff1a;CSDN一位小博主&#xff0c;正在学习前端&#xff0c;欢迎大家一起来交流学习&#x1f3c6; &#x1f4c3;个人主页&#xff1a;白月光777的CSDN博客 &#x1f525;系列专栏&#xff1a;Vue从入门到进阶 &#x1f4ac;个人格言&#xff1a;但行好事&…...

python 正则使用详解

python 正则使用详解什么是正则在 python 中使用正则一些正则的定义python 正则的方法match 从字符串开头匹配正则返回的结果分析&#xff08;重要&#xff09;fullmatch 严格匹配整个字符串search 任意位置开始匹配sub 替换匹配内容subn 以元组方式返回替换结果split 正则切割…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...