关于多线程

并发编程

在计算机的操作系统中,我们了解到了进程管理,有了解到了cpu的特性,核心数和频率,在次之前我们所写的代码都是只用到了一个核心,此时无论你怎么优化代码,最多也只能使用到一个cpu的核心,把这个核心跑满了,其他的核心也是闲着,所以我们可以通过特殊的编写代码,把多个CPU的核心都能利用起来,这样的代码就称"并发编程",多进程编程也是一种典型的并发编程.

线程的由来

虽然多进程能够解决问题,但是随着对于效率要求越来越高,希望有更好的方式来进行并发编程,多进程编程,最大的问题就是太重了,创建进程/销毁进程,开销比较大(时间和空间),一旦需求场景需要频繁的创建销毁线程,开销就会非常明显了,最典型的就是服务器开发,针对每个发送请求的客户端,都创建一个独立的进程,由着个进程给客户端提供服务.为了解决进程开销的问题,发明了线程(Thread)

线程

线程可以理解成更轻量级的进程,也可以解决并发编程的问题,但是创建/销毁线程比进程开销更低,因此多线程编程成为更主流的并发编程方式,

所谓的进程,在系统中,是通过PCB结构体来描述的,也是通过链表的形式连接起来的,对于系统中,线程,同样也是通过PCB来描述的(Linux)

一个进程是一组PCB,一个线程是一个PCB,存在了包含关系,一个进程中至少有一个线程,也可以有多个线程,但不能没有线程,此时,每个线程都可以,独立到CPU上调度执行,线程是系统调度执行的基本单位 ,进程是系统进行资源分配的基本单位

一个可执行程序,运行的时候(双击),操作系统就会创建线程,给这个程序分配各种系统资源(CPU,内存,硬盘,网络带宽),同时也会在这个进程中,创建出这个一个或者多个线程,这些线程再去CPU上进行调度,

如果有多个线程在一个进程中,每个线程都会有自己的状态,优先级,记账信息,上下文,每个都会各自独立在CPU上调度执行,同一个进程中的这些线程,共用同一份系统资源,线程比进程更轻量,主要在于,创建线程省去了"分配资源"的过程,销毁线程也省去了"释放资源"的过程,一旦创建进程就会创建线程,系统就会分配资源,后续创建第二个第三个线程的时候,就不会再重新分配资源了.

适当提升线程数目,可以提高效率,关键是利用多核心,进行"并行执行",如果线程数目太多,超出了CPU的核心数,就会适得其反,线程之间相互抢占资源,由于多个线程,使用的是同一份资源(内存资源)->代码中定义的对象/变量,如果多个线程对同一个变量进行读写(尤其是写),就容易引起冲突,一旦发生冲突就可能程序出问题.

当一个进程中,有多个线程的时候,一旦某个线程抛出异常,这个时候,如果能够妥善处理,还好一旦处理不当,就可能导致进程崩溃,因此其他线程也会随之崩溃了.

所谓的"核心"是CPU的核心~硬件设备,而进程是系统管理的软件资源,进程也叫任务,任务需要交给核心来执行,每个进程中又可以包含多个线程

理解并行和并发 

在微观角度看,多个核心,每个核心都可以执行一个线程,这些核心之间的执行过程是"同时执行的"并行,

一个核心,"分时复用",来切换多个线程,多个线程是一个接一个的执行,由于调度速度够快,宏观是看起来好像是同时执行,称为并发执行

进程线程的概念区别

1.进程包含线程,一个进程中至少有一个线程,也可以有多个线程,但不能没有线程

2.进程是系统分配资源的基本单位,线程是系统执行调度的基本单位

3.同一个进程里的线程之间,共用同一份系统资源(内存,硬盘,网络带宽等.....)尤其是"内存资源",就是代码中定义的对象/变量,编程中,多个线程可以共用同一份变量.

4.线程是当下实现并发编程的主流方式,通过多线程,就可以充分利用好多核心CPU,但是也不是线程数目越多,越好线程数目达到一定程度,把多个核心都充分利用好了之后,此时继续增加线程,无法在提高效率,甚至可能会影响效率(线程调度,也是有开销的)

5.多个线程之间,可能会相互影响,线程安全问题,一个线程抛出异常,也可能把其他线程一起带走

6.多个进程之间,一般不会相互影响,一个进程崩溃了,不会影响到其他进程(这一点也成为"进程的隔离性")

如何在Java代码中,编写多线程程序

线程,本身是操作系统提供的概念,操作系统提供API,供程序员使用,不同的操作系统,提供的API是不同的,而Java(JVM)把这些系统API封装好了,只需了解Java提供的这一套API就行

Thread(标准库),这个类就负责完成多线程的相关开发,此处这个类可以直接使用,不需要导入任何的包,在Java中,Java.lang默认自动导入

重新run方法

随后通过调用start()方法,就会在进程内部创建出一个新的线程,新的线程就会执行刚刚run的代码,

此时没有调用run方法,但是最终被执行了,这样的方法就成为回调函数,用户手动定义了,但是没有手动调用,最终这个方法被系统/库/框架调用了

这个方法是Thread的静态方法,通过类名.方法名进行调用

从编译角度理解:静态理解成编译过程中确定的,动态理解成运行过程中确定的,除了重写的方法,动态绑定,运行时确定,不去重写,也就是静态的

前台线程:如果这个线程在执行过程中,不能阻止进程结束,(虽然线程在执行过程中,但是进程要结束了,此时线程也会随之被带走),这样的线程就叫做前台线程.

后台线程:如果线程在执行过程中,能够阻止进程的结束,此时就是后台线程

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

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

相关文章

搭建python虚拟环境,并在VSCode中使用

创建环境 python -m venv E:\python\flask\venv激活环境 运行下图所示的bat文件 退出环境 执行下面的语句 deactivateVSCode中配置: ①使用CTRLshiftp命令,使用CTRLshiftp命令,输入: Python: Select Interpreter②选择之前创建…

数据库-列的完整性约束-概述

引言 我们都知道人以群分 ,但分为 若按照 人类的皮肤分类 黄种人(其实是西方人定义)我们虽然不承认也不否定 ,黑皮肤 ,棕色人种(在南太平洋和西太)白种人 排名你懂的 这好像是枚举类型 emm 尴尬…

【线性代数】向量空间,子空间

向量空间 设V为n维向量的集合,如果V非空,且集合V对于向量的加法以及数乘两种运算封闭,那么就称集合V为向量空间 x,y是n维列向量。 x 向量组等价说明可以互相线性表示 向量组等价则生成的向量空间是一样的 子空间 例题18是三位向…

三、【源码】Mapper XML的解析和注册使用

源码地址:https://github.com/mybatis/mybatis-3/ 仓库地址:https://gitcode.net/qq_42665745/mybatis/-/tree/03-parse-mapperXML Mapper XML的解析和注册使用 流程: 1.Resources加载MyBatis配置文件生成Reader字符流 2.SqlSessionFact…

考虑风光场景生成的电动汽车并网优化调度【遗传算法】【IEEE33】

目录 主要内容 部分代码 部分结果 下载链接 主要内容 程序主要内容是考虑风光场景生成的电动汽车并网优化调度,采用的方法如下所述: ①采用蒙特卡洛方法,结合copula函数以及fuzzy-kmeans,获取6个典型风光出力场景&…

【Pytorch】计算机视觉项目——卷积神经网络TinyVGG模型图像分类(如何使用自定义数据集)

目录 一、前言二、工作流程回顾三、详细步骤流程1. 环境配置2. 数据准备数据集下载数据存储结构&路径查看图片 3. 数据转换4. 自定义数据集(Custom Dataset )4.1 方法一:使用ImageFolder加载数据集信息查看张量转图片创建DataLoader 4.2 …

计算机毕业设计项目、管理系统、可视化大屏、大数据分析、协同过滤、推荐系统、SSM、SpringBoot、Spring、Mybatis、小程序项目编号1-500

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

芯片软件复位的作用

在调试系统或现场使用时,常用软件复位而不是频繁地通过断电来实现复位操作有以下优劣势: 优势: 数据完整性:通过软件复位,系统可以在一个受控的环境中重新启动,确保数据的完整性和一致性,避免…

阿奇科技 简单java-swing计算器源码(可用于课设等)

此系统用的技术有java swing! 实现的功能: 加减乘除(可以进行小数运算) 清空数据 最小化 小巧方便,功能齐全! 页面截图: 源码地址:点击这里下载源码 获取全套代码,或咨询更多代码…

uC-OS-III多任务程序

目录 一、STM32CubeMX基于HAL库建立工程 1、配置RCC 2、配置SYS 3、配置GPIO输出口 4、串口配置 5、系统时钟频率配置 二、uC/OS-III下载 三、文件移植 1、uC-BSP文件夹中添加文件 2、uC-CONFIG文件夹中添加文件 3、HAL工程的MDK-ARM文件夹设置 4、uC-CPU文件夹设置…

【数据结构】顺序表专题(学习记录)

正文开始 课前预备 1. 课程目标 C语言语法基础到数据结构与算法,前⾯已经掌握并具备了扎实的C语言基础,为什么要学习数据结构课程?⸺通讯录项目 2. 需要的储备知识 简单了解,通讯录具备增加、删除、修改、查找联系⼈等操作。要想…

RabbitMQ--Hello World(基础详解)

文章目录 先决条件RabbitMQ 初识RabbitMQ--Hello World发送接收 更多相关内容可查看 先决条件 本教程假定 RabbitMQ 已安装并在标准端口 (5672) 上运行。如果你 使用不同的主机、端口或凭据,连接设置将需要 调整。如未安装可查看Windows下载…

【Ardiuno】ESP32单片机初试点亮LED小灯

之前用的Ardiuno的主板做过一些简单的开发实验,按照相关说明还是很容易进行操作的。最近看了ESP32可以有wifi的功能,也就买来实验一下。 ESP32的主板开发环境安装,按照说明的安装下载程序总是报错,又上网搜索半天最后按照CSDN上某…

C语言实战:贪吃蛇(万字详解)

💡目录 效果图 界面设计思路 1. 基本布局 2. 视觉元素 游戏机制设计 基本规则 游戏代码 前期准备 游戏代码详解 数据结构设计 宏定义 数据结构定义 函数原型(详见后文) 主函数代码 核心代码 Review 效果图 界面设计思路 1. 基…

【应用浅谈】Odoo的库存计价与产品成本(三)

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo的库存(Stock)模块拥有众多功能,其中库存计价是一项非常重要的功能,原生的成本方法分三种:【标准成本】,【平均成本】,【先进先出】&#…

【C++11】多线程常用知识

知识体系 thread C++ thread中最常用的两个函数是join和detach,怎么选择呢,简单来说,如果希望等待线程结束,用join,如果希望异步执行,且不等待执行结果,那么就用detach;thread_local可以简单理解为一个线程级别的全局变量;线程id在调试多线程程序时是非常有用的东西;…

YOLOv8_obb的训练、验证、预测及导出[旋转目标检测实践篇]

1.旋转目标检测数据集划分和配置 从上面得到的images和labels数据还不能够直接训练,需要按照一定的比例划分训练集和验证集,并按照下面的结构来存放数据,划分代码如下所示,该部分内容和YOLOv8的训练、验证、预测及导出[目标检测实践篇]_yolov8训练测试验证-CSDN博客是重复的…

3. redis常见部署架构

redis常见部署架构 一、redis常见部署架构1、常见部署架构2、多实例部署2.1 规划安装目录、配置文件2.2.2 编辑实例配置文件2.2.3 启动实例2.2.4 测试数据读写 3、redis主从复制3.1 规划3.2 从服务器配置3.3 验证主从状态3.4 主从角色切换 4、分片集群4.1 原理4.2 分片集群的部…

SystemVerilog Interface Class的妙用

前言 Interface Class是在SystemVerilog 2012版本中引入的,但目前在验证中几乎很少采用,大多数验证工程师要么不知道它,要么没有看到使用它的任何好处,这使得Interface Class成为一个未被充分使用和不被重视的特性。本文将举两个…

【越界写null字节】ACTF2023 easy-netlink

前言 最近在矩阵杯遇到了一道 generic netlink 相关的内核题,然后就简单学习了一下 generic netlink 相关概念,然后又找了一到与 generic netlink 相关的题目。简单来说 generic netlink 相关的题目仅仅是将用户态与内核态的交互方式从传统的 ioctl 变成…