进程与线程、线程创建、线程周期、多线程安全和线程池(ThreadPoolExecutor)
目录
- 进程与线程
- 线程和进程的区别是什么?
- 线程分两种:用户线程和守护线程
- 线程创建四种方式
- run()和start()方法区别:
- 为什么调用 start() 方法时会执行 run() 方法,为什么不能直接调用 run() 方法?
- Runnable接口和Callable接口有何区别
- 线程声明周期的6种状态
- 如何保证多线程安全的?
- 什么是线程安全?
- 如何保证多线程安全的
- 线程同步和线程互斥的区别
- 如何同步线程?
- 如何避免线程死锁?
- 死锁的四个必要条件:
- 避免线程死锁
- 如何优化多线程程序的性能?
- 什么是线程池?它的优点?
- 为什么要使用线程池?
- 创建线程池:ThreadPoolExecutor
- ThreadPoolExecutor构造函数七大参数
- 拒绝任务策略:
- 乐观锁和悲观锁的理解?
进程与线程
什么进程?
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
什么是线程?
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。
- 对于单核CPU而言:多线程就是一个CPU在来回的切换,在交替执行。
- 对于多核CPU而言:多线程就是同时有多条执行路径在同时(并行)执行,每个核执行一个线程,多个核就有可能是一块同时执行的。
线程和进程的区别是什么?
进程是资源分配的最小单位,而线程是程序执行的最小单位。一个进程可以包含多个线程,线程之间共享进程的资源,但每个线程都有自己的栈空间和寄存器。
线程分两种:用户线程和守护线程
用户线程:如果主线程main停止掉,不会影响用户线程,用户线程可以继续运行。
守护线程:为其他线程服务的,如果主线程死亡,守护线程如果没有执行完毕也要跟着一块死,GC垃圾回收线程就是守护线程
线程创建四种方式
- 继承 Thread,重写run方法
- 实现 Runable,重写run方法
- 实现 Callable,重写run方法
- Executors工具类创建线程池
一般推荐使用 ThreadPoolExecutor创建线程池
run()和start()方法区别:
run():仅仅是封装被线程执行的代码,直接调用是普通方法
start():首先启动了线程,这时此线程处于就绪(可运行)状态,然后再由jvm去调用该线程的run()方法。
为什么调用 start() 方法时会执行 run() 方法,为什么不能直接调用 run() 方法?
调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。
Runnable接口和Callable接口有何区别
相同点:
- Runnable和Callable都是接口
- 都可以编写多线程程序
- 都采用Thread.start()启动线程
不同点:
- Runnable接口run方法无返回值,Callable接口call方法有返回值,是个泛型,和Futrue和FutureTask配合用来获取异步执行结果。
- Runable接口run方法只能抛出运行时的异常,且无法捕获处理;Callable接口call方法允许抛出异常,可以获取异常信息。
线程声明周期的6种状态
-
创建:又称初始化状态,这个时候Thread才刚刚被new出来,还没有被启动。
-
可运行:表示已经调用Thread的start方法启动了,随时等待CPU的调度,此状态又被称为就绪状态。
-
阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态
- 阻塞的情况分三种:
(一). 等待阻塞:运行状态中的线程执行 **wait()**方法,JVM会把该线程放入等待队列(waitting queue)中,使本线程进入到等待阻塞状态;
(二). 同步阻塞:线程在获取 synchronized 同步锁失败(因为锁被其它线程所占用),,则JVM会把该线程放入锁池(lock pool)中,线程会进入同步阻塞状态;
(三). 其他阻塞: 通过调用线程的 **sleep()**或 **join()**或发出了 I/O 请求时,线程会进入到阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。
- 阻塞的情况分三种:
-
等待:获取锁对象后,调用wait()方法,释放锁进入无线等待状态
-
计时等待:调用sleep(参数)或wait(参数)后线程进入计时状态,睡眠时间到了或wait时间到了,再或者其它线程调用notify并获取到锁之后开始进入可运行状态,避免了无期限的等待。
-
死亡:表示已经正常执行完线程体run()中的方法了或者因为没有捕获的异常而终止run()方法了。
如何保证多线程安全的?
什么是线程安全?
线程安全:指某个方法在多线程环境被调用,能够正确处理多线程之间的共享变量,是程序功能正确完成。
如何保证多线程安全的
- 使用安全类,比如 java.util.concurrent 下的类,使用原子类AtomicInteger
- 使用自动锁 synchronized。
- 使用手动锁 Lock。
线程同步和线程互斥的区别
线程同步
:当一个线程对共享数据进行操作的时候,在没有完成相关操作时,不允许其它的线程来打断它,否则就会破坏数据的完整性,必然会引起错误信息。
线程互斥
:线程互斥是站在共享资源的角度上看问题,例如某个共享资源规定,在某个时刻只能一个线程来访问我,其它线程只能等待,知道占有的资源者释放该资源,线程互斥可以看作是一种特殊的线程同步。
如何同步线程?
可以使用互斥锁、条件变量、信号量等机制来同步线程。互斥锁用于保护共享资源,条件变量用于线程之间的通信,信号量用于控制并发访问。
如何避免线程死锁?
死锁的四个必要条件:
-
互斥条件:进程对所分配到的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
-
请求和保持条件:进程已经获得了至少一个资源,但又对其他资源发出请求,而该资源已被其他进程占有,此时该进程的请求被阻塞,但又对自己获得的资源保持不放。
-
不可剥夺条件:进程已获得的资源在未使用完毕之前,不可被其他进程强行剥夺,只能由自己释放。
-
循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。
避免线程死锁
预防死锁的方式就是打破四个必要条件中的任意一个即可。
避免线程死锁的方法包括:避免嵌套锁,按照固定的顺序获取锁,使用超时机制,避免资源竞争等。此外,还可以使用死锁检测工具来检测和解决死锁问题。
如何优化多线程程序的性能?
可以采用以下方法来优化多线程程序的性能:避免线程之间的竞争,减少锁的使用,使用无锁数据结构,使用线程池等。此外,还可以使用性能分析工具来找出程序的瓶颈,进行优化。
什么是线程池?它的优点?
事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
- 优点
- 降低资源消耗:重用存在的线程,减少对象创建销毁的开销。
- 提高响应速度:可有效的控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
- 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
- 附加功能:提供定时执行、定期执行、单线程、并发数控制等功能。
为什么要使用线程池?
如果我们在方法中直接new一个线程来处理,当这个方法被调用频繁时就会创建很多线程,不仅会消耗系统资源,还会降低系统的稳定性,一不小心把系统搞崩了。合理的使用线程池,则可以避免把系统搞崩的窘境,这说一下线程池的好处:降低资源消耗、提高响应速度和提高线程的可管理性。
创建线程池:ThreadPoolExecutor
Executors和ThreaPoolExecutor创建线程池的区别
Executors 各个方法的弊端:
- newFixedThreadPool 和 newSingleThreadExecutor:
主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。 - newCachedThreadPool 和 newScheduledThreadPool:
主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。
ThreadPoolExecutor创建线程池方式只有一种,就是走它的构造函数,参数自己指定。
ThreadPoolExecutor构造函数七大参数
核心线程数(corePoolSize )
: 线程数定义了最小可以同时运行的线程数量;最大线程数(maximumPoolSize )
:线程池中允许存在的工作线程的最大数量;允许线程空闲时间(keepAliveTime)
:线程池中的线程数量大于核心线程数的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 空闲时间才会被回收销毁;时间单位(unit )
:参数的时间单位;队列(workQueue)
:当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,任务就会被存放在队列中;线程工厂(threadFactory)
:为线程池提供创建新线程的线程工厂;拒绝策略(handler )
:线程池任务队列超过最大线程数之后的拒绝策略,默认直接抛出异常。
拒绝任务策略:
- 中止策略(AbortPolicy):抛出 RejectedExecutionException来拒绝新任务的处理;
- 调用者策略(CallerRunsPolicy):调用执行自己的线程运行任务;
- 抛弃策略(DiscardPolicy):什么都不做,直接丢弃掉;
- 抛弃最老最老策略(DiscardOldestPolicy):丢弃最早的未处理的任务请求。
乐观锁和悲观锁的理解?
乐观锁:每个去拿数据的时候都认为别人不会修改,所以不会都不会上锁,但是在更新的时候会判断一下在此期间有没有去更新这个数据。所以乐观锁使用了多读的场合,这样可以提高吞吐量,像数据库提供的类似write_condition机制,都是用的乐观锁。
悲观锁:总是认为出现问题,每次去拿数据的时候都会认为有人会修改,所以每次在拿数据的时候都会上锁。这样别的对象想拿到数据,那就必须堵塞,直到拿到锁。传统的关系型数据库用到了很多这种锁机制,比如读锁,写锁,在操作之前都会先上锁,再比如Java的同步代码块synchronized/方法用的也是悲观锁。
相关文章:

进程与线程、线程创建、线程周期、多线程安全和线程池(ThreadPoolExecutor)
目录 进程与线程线程和进程的区别是什么?线程分两种:用户线程和守护线程线程创建四种方式run()和start()方法区别:为什么调用 start() 方法时会执行 run() 方法,为什么不能直接调用 run() 方法?Runnable接口和Callable…...

《论文阅读13》Efficient Urban-scale Point Clouds Segmentationwith BEV Projection
一、论文 研究领域: 城市级3D语义分割论文:Efficient Urban-scale Point Clouds Segmentationwith BEV Projection论文链接 注: BEV: Birds Eye View BEV投影是指鸟瞰视角(Birds Eye View,简称BEV)的一种从上方观看对象或场景的…...

Django实现音乐网站 ⑻
使用Python Django框架制作一个音乐网站, 本篇主要是后台对单曲原有功能的基础上进行部分功能实现和显示优化。 目录 新增编辑 歌手下拉显示修改 设置歌曲时长 安装eyed3库 获取mp3时长 歌曲时长字段修改 重写save方法 增加歌手单曲数量 查询歌手单曲数量 …...

VScode中同时打开两个脚本
使用快捷键: CtrlAltRightArrow 效果: 可以看到,上述两个脚本使用独立的窗口进行编辑和查看。...
能源电力工程师专属Python学习资料
随着我国新型电力系统的建设,一方面电源侧各类新能源装机快速增长,对于新能源出力的功率预测需求日益增长;另一方面,我国电力市场经过 8 年建设,关于电力商品价格影响因素的研究亟待深入。超过 90% 的业务小伙伴都具备…...

推荐5款实用软件,提高工作效率,丰富生活乐趣
分享软件会让我感到开心和满足,因为我知道这些软件可以提高工作效率,丰富生活乐趣。今天再次将几款非常实用的软件推荐给大家。 截图翻译工具——CopyTranslator CopyTranslator是一款非常实用的截图翻译软件,它支持对截图、选定区域进行OCR文字识别,自动翻…...

Python爬虫在电商数据挖掘中的应用
作为一名长期扎根在爬虫行业的专业的技术员,我今天要和大家分享一些有关Python爬虫在电商数据挖掘中的应用与案例分析。在如今数字化的时代,电商数据蕴含着丰富的信息,通过使用爬虫技术,我们可以轻松获取电商网站上的产品信息、用…...

element-ui 表格el-table的列内容溢出省略显示,鼠标移上显示全部和定制样式
1、在对应列加上省略显示show-overflow-tooltip属性,如果加上这属性,鼠标移上还是没效果,要考滤是不是层级的原因,被其他挡住了。 :deep(.el-tooltip){position: relative;z-index:9; } <el-table-column label"用款渠…...

研究人员发现特斯拉汽车能被越狱,可免费解锁付费功能
Bleeping Computer 网站披露,柏林工业大学(Technical University of Berlin)的研究人员开发出一种新技术,可以破解特斯拉近期推出所有车型上使用的基于 AMD 的信息娱乐系统,并使其运行包括付费项目在内的任何软件。 实…...

【设计模式】责任链的基本概念及使用Predicate灵活构造校验链
文章目录 1. 概述1.1.背景1.2.责任链模式的概念 2.责任链的基本写法2.1.链表实现2.2.数组实现 3.Predicate校验链2.1.使用Predicate改写代码2.1.更丰富的条件拓展 4.总结 1. 概述 1.1.背景 在最近的开发中遇到了这么一个需求,需要对业务流程中的各个参数做前置校验…...
Taro保存图片到手机
萌新亚历山大啊,搞了一下午,真多坑 Taro.downloadFile({url: res,filePath: Taro.env.USER_DATA_PATH /xcxcode.jpg,success: res > {if (res.statusCode 200) {console.log(res)const tempFilePath res.filePath; // 获取下载的临时文件路径// …...

zookeeper --- 基础篇
一、zookeeper简介 1.1、什么是zookeeper zookeeper官网:https://zookeeper.apache.org/ 大数据生态系统里的很多组件的命名都是某种动物或者昆虫,他是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小 猪)的管理员。顾名思义就是管理…...
Golang map 常用方法
文章目录 前言按key排序按value排序统计字符串中元素重复出现次数并将结果排序返回 前言 由于map是无序的,所以排序成 slice 返回,且都使用泛,代码只是示例,省略了错误判断 按key排序 package mainimport "fmt"func example[T c…...

用于视觉跟踪的在线特征选择研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Docker基本使用
查看本地镜像 查看本地:docker imagesPull镜像:docker pull nginx:latest登录镜像:docker login hub.docker.com -u **** -p ****制作镜像:docker build -t xxxx:v1push:docker push xxx:v1删除镜像:docker rmi #imag…...
PHP生成随机数
要在 PHP 中生成随机密码,可以使用 rand() 函数和字符串操作函数。以下是一个示例代码来生成包含字母、数字和特殊字符的随机密码 function generateRandomPassword($length 8) {// 定义包含字母、数字和特殊字符的字符集$characters abcdefghijklmnopqrstuvwxyz…...

MongoDB:Unrecognized option: storage
MongoDB一直显示 Unrecognized option: storage try ‘mongod --help’ for more information 意思是我们配置的config文件出了问题。 说明:MongoDB采用的是YAML格式,所以我们只需要稍微改改就好。 在storage前面:没有空格 下面两行最前面…...
Java基础九 - 异常
1. throw 和 throws 1. throw是在代码运行过程中引起一个异常 2. throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理 2. final、finally、finalize 1. final是修饰符,用于修饰变量、方法、类修饰变量,最开始…...
[国产MCU]-BL602开发实例-UART数据发送与接收
UART数据发送与接收 文章目录 UART数据发送与接收1、BL602的UART介绍2、UART相关驱动API介绍3、UART使用示例3.1 轮询方式数据接收与发送3.2 中断方式数据接收与发送3.3 DMA方式接收与发送数据通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为UART)…...

mac安装open3d时候出现错误
在测试open3d是否正常顺利安装时,出现了如下错误: python -c "import open3d as o3d; print(o3d.__version__)" Traceback (most recent call last):File "<string>", line 1, in <module>File "/Users/huangzhe/…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...