从零全面认识 多线程

目录

 1.基本概念

2.创建线程方式

2.1直接建立线程

2.2实现Runnable接口

3.3实现Callable接口

3.4 了解Future接口

Future模式主要角色及其作用

3.5实例化FutureTask类

3.实现线程安全

3.1定义

3.2不安全原因

3.3解决方案

3.4volatile与synchronized区别

3.5Lock与sychronized区别

4.极端情况——线程死锁

4.1定义

4.2解决措施

5.线程池的掌握

5.1核心参数

5.2生命周期

5.3处理流程

5.4Handler拒绝策略

5.5常见线程池

5.6线程池的使用


 1.基本概念

线程状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、

                  等待(Waiting)、超时等待(Timed Waiting)、终止(Terminated)

锁(同步监视器):分为悲观锁和乐观锁,常见的有偏向锁、轻量级锁、重量级锁

                                CAS(Compare And Swap)是一种乐观锁的实现方式,通过比较并

                                交换来实现并发控制

2.创建线程方式

Runnable接口、Callable接口、Future接口、FutureTask类

2.1直接建立线程

        创建Thread子类,按需求重写run()方法 【run代表此线程执行时会做的事】

        这里的属性若为 多线程共享属性,加static修饰

2.2实现Runnable接口

 这里的 多线程共享属性 可以是非静态的,因为多线程共用此接口

3.3实现Callable接口

(1)实现接口Callable,重写call()回调方法,会返回一个值,值类型由Callable泛型决定

实例化上述类,利用FutureTask(Callable)构造器实例化类

3.4 了解Future接口

异步调用的多线程开发模式之一(异步:当我们需要调用一个函数方法时,并不急着要结果。让被调者立即返回,让它在后台慢慢处理这个请求;此时则可以先处理一些其他任务

Future模式主要角色及其作用

Main->调用Client发送请求

Data->返回数据的接口

Client->返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData

FutureData->虚拟数据,伪造数据立即返回,最终装配上RealData

RealData->真实数据,构造缓慢

3.5实例化FutureTask类

FutureTask用于异步获取执行结果或取消执行任务

通过传入Runnable或者Callable的任务给FutureTask,

直接调用其run方法或者放入线程池执行,

最后在外部通过FutureTask的get方法异步获取执行结果(适合耗时操作)

3.实现线程安全

3.1定义

多线程环境下,对共享资源的访问不会导致数据出错。

因此和单线程执行相同的操作,结果相同

3.2不安全原因

1. 线程是抢占式的执行,线程间的调度充满了随机性
2. 多个线程对同一个变量进行修改操作
3. 对变量的操作不是原子性的
4. 内存可见性导致的线程安全问题
5. 指令重排序也会影响线程安全

3.3解决方案

使用同步机制(如synchronized、Lock)、

使用线程安全的数据结构(如ConcurrentHashMap)

synchronized:Java关键字,属于隐式锁,可以修饰方法或代码块

Lock:JAVA接口,显式锁

原理上都是通过对共享资源加锁来实现同步。

3.4volatile与synchronized区别

volatile轻量级的锁,保证变量的可见性和有序性,但仅仅保证单个变量的原子性

可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入,解决多核CPU缓存可见性问题

有序性:采用内存屏障来实现的,就是在编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序

原子性:对单个volatile变量的读写具有原子性,对“volatile变量++”这种复合操作则不具有原子性,

而synchronized既保证可见性又保证原子性

volatile适用于单个变量的读写操作,而synchronized适用于复合操作或临界区。

3.5Lock与sychronized区别

使用方式: 1、Lock接口是显式锁,即我们需要调用其内部定义的方法显式地加锁和解锁,更加灵活,Lock对象创建Condition对象来实现线程通信

                   2、synchronized关键字是隐式锁,无需显式地获取和释放锁,使用方便

 功能特性:Lock弥补了synchronized的不足,它新增了特性:1、可中断地获取锁,2、 非阻塞地获取锁,3、可超时地获取锁

实现机制:AQS是队列同步器,是用来构建锁的基础框架,Lock实现类都是基于AQS实现的

                  synchronized的底层是采用Java对象头来存储锁信息的,对象头包含三部分,分别是Mark Word、Class Metadata Address、Array length。

4.极端情况——线程死锁

4.1定义

多个线程相互等待对方释放资源,导致无法继续执行

4.2解决措施

  1. 避免嵌套锁、

  2. 按固定的顺序获取锁、

  3. 设置超时时间、

  4. 使用Lock对象代替synchronized关键字。

5.线程池的掌握

5.1核心参数

核心线程数(corePoolSize):依据任务的处理时间和每秒产生的任务数量来确定

最大线程数(maximumPoolSize):参照核心线程数和系统每秒产生的最大任务数决定

线程空闲时间(keepAliveTime):用户自设置合理时间间隔

任务队列(workQueue):一定的顺序或优先级来执行任务

拒绝策略(handler):线程池已经关闭或达到饱和(最大线程和队列都已满)状态时,新提交的

                                任务将会被拒绝。

5.2生命周期

线程池的生命周期包含5个状态:

  • RUNNING:线程池正在运行,接受新任务并执行。
  • SHUTDOWN:任务队列不清空,线程池不再接受新任务,等待执行的任务继续执行完毕。
  • STOP:清空任务队列,不等待执行的任务,尝试终止正在执行的任务。
  • TIDYING:当线程池及任务队列为空时进入该状态,线程池会执行钩子函数(待实现)。
  • TERMINATED:线程池终止状态,所有任务执行完毕,线程池关闭。

注意:

在线程池的生命周期中,它的状态是不可逆

5.3处理流程

向线程池提交一个任务之后,线程池按照如下步骤处理这个任务

注意:

1、新建的线程处理完当前任务后,变为空闲线程,继续处理等待队列中的任务。

2、如果线程的空闲时间达到了keepAliveTime,则线程池会销毁一部分线程,将线程数量收缩至corePoolSize。

5.4Handler拒绝策略

Hanlder通常处理消息,但线程池中帮助任务异步执行,发送消息并执行UI更新等操作

拒绝策略分别对应着RejectedExecutionHandler接口的4个实现类,

1、让调用者自己执行任务

2、直接抛出异常

3、丢弃任务不做任何处理

4、删除队列中最老的任务并把当前任务加入队列

5.5常见线程池

FixedThreadPool、CachedThreadPool、ScheduledThreadPool

5.6线程池的使用

1:利用Executors工厂类的静态方法,创建线程池对象;
2:编写Runnable或Callable实现类的实例对象;
3:利用ExecutorService的submit方法或ScheduledExecutorService的schedule方法提交并执行线程任务
4:如果有执行结果,则处理异步执行结果(Future)
5:调用shutdown()方法,关闭线程池

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

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

相关文章

第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏,又增加了哔哩哔哩搜索和必应搜索

第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏&#xff0c;又增加了哔哩哔哩搜索和必应搜索. <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"…

THS6.0.1.0开启健康检查(by lqw)

可以在节点管理器或者分组管理的编辑配置里添加以下信息&#xff1a; 之后点监控,点击实时指标&#xff0c;点击HTTP集群统计&#xff1a; 下图是配置并生效的效果&#xff1a; 也可以使用頁面配置&#xff1a; 推荐使用tcp形式&#xff0c;有的应用后端可能不支持http…

微信跳转页面时发生报错

报错如下图所示&#xff1a; 解决方法&#xff1a;&#xff08;从下面四种跳转方式中任选一种&#xff0c;哪种能实现效果就用哪个&#xff09; 带历史回退 wx.navigateTo() //不能跳转到tabbar页面 不带历史回退 wx.redirectTo() //跳转到另一个页面wx.switchTab() //只能…

SpringBoot项目接入Nacos注册中心

前置 已经安装好Nacos服务&#xff0c;并且该项目所在服务器可以访问到 可以参考下&#xff1a; windows环境安装Nacos单机版-CSDN博客 Centos7安装Nacos单机版-CSDN博客 1. POM文件引入依赖 注意&#xff0c;父工程已经引入spring cloud依赖管理的情况下不用添加版本号 …

Leetcode二十三题:合并K个升序链表【22/1000 python】

“合并K个升序链表”&#xff0c;这是一道中等难度的题目&#xff0c;经常出现在编程面试中。以下是该问题的详细描述、解题步骤、不同算法的比较、代码示例及其分析。 问题描述 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中…

如何在Photoshop中,使用本地Stable Diffusion WebUI的绘图能力

&#x1f3c3;‍♂️文章背景 相信设计师朋友们最熟悉的软件应该就是photoshop了&#xff0c;现在AI绘图虽然控制性越来越强&#xff0c;但跟ps比起来&#xff0c;还是要弱很多&#xff0c;尤其是图层、蒙版、笔刷、色调校色等等功能&#xff0c;所以就算是使用SD或者midjourn…

数据分析案例(三):基于RFM分析的客户分群

实验2 基于RFM分析的客户分群 Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢…

RabbitMQ-死信队列常见用法

目录 一、什么是死信 二、什么是死信队列 ​编辑 三、第一种情景&#xff1a;消息被拒绝时 四、第二种场景&#xff1a;. 消费者发生异常&#xff0c;超过重试次数 。 其实spring框架调用的就是 basicNack 五、第三种场景&#xff1a; 消息的Expiration 过期时长或队列TTL…

【Linux】序列化与反序列化{服客编程/守护进程/JSON}

文章目录 1.引入2. 静态成员函数3.TCP&#xff1a;传输控制协议4.守护进程4.0前台进程4.1介绍4.2认识4.3会话4.3ps axj4.4理解4.5/dev/null4.6守护进程和孤儿进程 5.JSON6.完整代码6.1Makefile6.2Socket.hpp6.3Protocol.hpp6.4Log.hpp6.5Daemon.hpp6.6TcpServer.hpp6.7Client.c…

【3GPP】【核心网】核心网/蜂窝网络重点知识面试题二(超详细)

1. 欢迎大家订阅和关注&#xff0c;3GPP通信协议精讲&#xff08;2G/3G/4G/5G/IMS&#xff09;知识点&#xff0c;专栏会持续更新中.....敬请期待&#xff01; 目录 1. 对于主要的LTE核心网接口&#xff0c;给出运行在该接口上数据的协议栈&#xff0c;并给出协议特征 2. 通常…

C++11 设计模式2. 简单工厂模式

简单工厂&#xff08;Simple Factory&#xff09;模式 我们从实际例子出发&#xff0c;来看在什么情况下&#xff0c;应用简单工厂模式。 还是以一个游戏举例 //策划&#xff1a;亡灵类怪物&#xff0c;元素类怪物&#xff0c;机械类怪物&#xff1a;都有生命值&#xff0…

内网渗透-Windows内网渗透

内网渗透-Windows内网渗透 文章目录 内网渗透-Windows内网渗透前言一、信息收集 1.1、SPN1.2、端口连接1.3、配置文件1.4、用户信息1.6、会话收集1.7、凭据收集 navicat&#xff1a;SecureCRT&#xff1a;Xshell&#xff1a;WinSCP&#xff1a;VNC: 1.8、DPAPI1.9、域信任1.10、…

3d怎么按路径制作模型---模大狮模型网

在3D建模中&#xff0c;按路径制作模型是一种常见的技术&#xff0c;特别适用于创建曲线、管道、绳索等线性形状的物体。虽然这项技术可能对初学者来说有些复杂&#xff0c;但通过一步步的指导和实践&#xff0c;你将能够掌握它。本文将详细介绍按路径制作模型的步骤&#xff0…

深拷贝总结

JSON.parse(JSON.stringify(obj)) 这行代码的运行过程&#xff0c;就是利用 JSON.stringify 将js对象序列化&#xff08;JSON字符串&#xff09;&#xff0c;再使用JSON.parse来反序列化&#xff08;还原&#xff09;js对象&#xff1b;序列化的作用是存储和传输。&#xff08…

认识OpenEuler操作系统

引言 在信息技术日新月异的时代&#xff0c;开源软件已成驱动创新的核心动能&#xff0c;其中&#xff0c;OpenEuler作为一款冉冉升起的开源操作系统典范&#xff0c;凭借其对开源精神的坚守与技术创新的不懈追求&#xff0c;自亮相以来便引发了全球关注。本文将全方位深挖Open…

一站式开源持续测试平台 MerterSphere 之测试跟踪操作详解

一、MeterSphere平台介绍 MeterSphere是一站式的开源持续测试平台&#xff0c;遵循 GPL v3 开源许可协议&#xff0c;涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&#xff0c;全面兼容JMeter、Selenium 等主流开源标准&#xff0c;有效助力开发和测试团队充分利用云弹性…

一分钟学会旋转一个矩阵

&#x1f60e; 作者介绍&#xff1a;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff0c;视频号&#xff1a;AI-行者Sun &#x1f388; 本文专栏&#xff1a;本文收录于《深入浅出算法》系列…

荔枝派LicheePi 4A RISCV板子支持的好玩的AI模型

荔枝派LicheePi 4A 是基于 Lichee Module 4A 核心板的 高性能 RISC-V Linux 开发板&#xff0c;以 TH1520 为主控核心&#xff08;4xC9101.85G&#xff0c; RV64GCV&#xff0c;4TOPSint8 NPU&#xff0c; 50GFLOP GPU&#xff09;&#xff0c;板载最大 16GB 64bit LPDDR4X&…

【Linux】账号和权限管理

目录 一、用户账号与组账号 二、添加用户账号-useradd 三、修改用户账号的属性-usermod 四、更改用户命令-passwd 五、删除用户账号-userdel 六、添加组账号-groupadd 七、添加删除组成员-gpasswd 八、删除组账号-groupdel 九、查询账号信息-groups、id、finger、w、w…

Ubuntu-22.04安装KVM虚拟机并安装Windows10

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、KVM是什么&#xff1f;二、安装步骤1.检查虚拟化2.查看KVM虚拟化3.安装KVM4.启用后台进程5.添加用户组6.重启电脑 三、使用步骤1.添加虚拟机2.配置虚拟机3.…