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

【JavaEE】多线程进阶

在这里插入图片描述
🤡🤡🤡个人主页🤡🤡🤡
🤡🤡🤡JavaEE专栏🤡🤡🤡

文章目录

  • 1.锁策略
    • 1.1悲观锁和乐观锁
    • 1.2重量级锁和轻量级锁
    • 1.3自旋锁和挂起等待锁
    • 1.4可重入锁和不可重入锁
    • 1.5公平锁和非公平锁
    • 1.6互斥锁和读写锁
  • 2.synchronized的实现原理
    • 2.1实现过程
    • 2.2偏向锁
    • 2.3优化策略
      • 2.3.1锁升级
      • 2.3.2锁消除
      • 2.3.3锁粗化
  • 3.CAS
    • 3.1什么是CAS
    • 3.2CAS的应用
      • 3.2.1原子类
      • 3.2.2实现自旋锁
    • 3.3CAS的ABA问题
      • 3.3.1ABA问题
      • 3.3.2ABA引起的BUG
      • 3.3.3如何避免由ABA问题引起的BUG
  • 4.java.util.concurrent常见类
    • 4.1Callable接口
    • 4.2ReentrantLock类
      • 4.2.1发音
      • 4.2.2ReentrantLock的关键特性与功能
    • 4.3Semaphore类——信号量

1.锁策略

1.1悲观锁和乐观锁

区别:加锁的时候,预测当前锁冲突的概率是大还是小
悲观锁:预测当前锁冲突概率大,后续要做的工作往往就会更多,加锁的开销(时间,系统资源)就更大。
乐观锁:预测当前锁冲突概率小,后续要做的工作往往就会更少,加锁的开销(时间,系统资源)就更小。
注意:悲观锁往往通过内核来完成操作的,所以做的工作多,乐观锁往往通过用户完成操作的,所以做的工作少。

1.2重量级锁和轻量级锁

这两个锁和上述的悲观锁和乐观锁有着很大的关系,一般悲观锁就是重量级锁,因为悲观锁做的任务多,那么就需要很大的开销所以就是重量级锁,反之乐观锁做的任务少,那么开销就少那么就是轻量级锁。
注意:一般这两个锁和上述两个锁都混着用,之所以有区别是因为出发点不一样。

1.3自旋锁和挂起等待锁

自旋锁:锁未被释放之前,cpu会一直空转和忙等,但等锁被释放之后就会立马获取到锁,自旋锁是实现轻量级锁典型的案例。
挂起等待锁:当出现锁冲突,那么要加锁的这个线程就会被挂起等待,此时的线程就不会参与调度,直到这个锁被释放,然后系统内核才唤醒这个线程,去尝试获取锁,拿锁的速度很慢,挂起等待锁是实现重量级锁的典型案例。

1.4可重入锁和不可重入锁

可重入锁:针对一个线程,可以连续加锁两次不会出现死锁,synchronized就是可重入锁。
不可重入锁:针对一个线程,连续加锁两次会出现死锁。像c++中的std::mutex就是不可重入锁

1.5公平锁和非公平锁

公平锁:严格按照先来后到的顺序来获取锁,哪个线程等待的时间长,哪个线程就拿到锁
非公平锁:若干个线程,各凭本事,随机获取锁和线程等待时间无关,synchronized就是一个非公平锁。
系统调度本来就是随机的,如果想实现一个公平锁,那么就需要引入一个特殊的队列来根据线程等待的时间来出队列。

1.6互斥锁和读写锁

互斥锁:加锁和解锁,synchronized就是一个互斥锁
读写锁:加读锁和加写锁,读与读之间不会产生互斥,写与写之间会产生互斥,读与写之间也会产生互斥,

2.synchronized的实现原理

2.1实现过程

未加锁(无锁状态)——>偏向锁——>轻量级锁——>重量级锁

2.2偏向锁

首次使用sychronized对对象加锁,此时并不是真正的加锁而是做了一个标记(非常轻量非常快,几乎没有开销)
如果在这其中没有其他线程对这个对象加锁,那么就一直保持这样的一个状态直到解锁的时候(解锁也只是修改标记,几乎没有开销)
但是如果在这期间,有其他对象对进行加锁,那么就会立马升级成轻量级锁。
注意:在这个升级过程中,是不可逆的,一旦升级了就不能降级(在目前版本的JVM中)

2.3优化策略

2.3.1锁升级

2.3.2锁消除

当你在这个代码中加了锁,编译器和JVM会检查当前代码需不需要加锁,不需要就会将这个锁帮你消除,这是在内部操作的,程序猿是感知不到的,例如我在单线程中加了锁,那么编译器和JVM就会把这个锁给消除。

2.3.3锁粗化

在有些逻辑中,需要频繁加锁和解锁,编译器就会自动把这些多次细粒度的锁合成一次粗粒度的锁,"粒度"是指加锁范围中代码的多少,代码越多粒度就越粗,反之越细。

3.CAS

3.1什么是CAS

CAS这是一个比较交换指令,而且这一指令详细的就是读取内存,比较是否相等,修改内存三个步骤,而与之前线程安全问题中多个线程对同一个变量进行修改操作是一样的,也是上述这三个步骤,但CAS这三个步骤是打包一起的是原子的,而对变量修改不是原子的,所以需要加锁,才能保证线程安全,所以CAS在某种程度也可以实现锁的功能。

3.2CAS的应用

3.2.1原子类

标准库中提供了 java.util.concurrent.atomic 包, ⾥⾯的类都是基于这种⽅式来实现的. 典型的就是 AtomicInteger 类.
在这里插入图片描述
通过方法来实现变量的算术运算

//count++
count.getAndIncrement();
//++count
count.incrementAndGet();
//count--
count.getAndDecrement();
//--count
count.decrementAndGet();
//count += 10
count.getAndAdd(10);

通过CAS实现两个线程对count变量相加

AtomicInteger count = new AtomicInteger(0);
Thread t1 = new Thread(()-> {for (int i = 0; i < 50000; i++) {count.getAndIncrement();}
});
Thread t2 = new Thread(()-> {for (int i = 0; i < 50000; i++) {count.getAndIncrement();}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("count = " + count);

这种编程方式也称为无锁编程,这种方式可以提高效率,但适用范围不大。

3.2.2实现自旋锁

由于在读取内存,比较相等,修改内存这三个步骤是原子,所以在某种程度上可以实现锁的功能
以下就是一段伪代码简单实现一下自旋锁

class SpinLock{public Thread owner = null;public void lock() {while(!CAS(this.owner,null,Thread.currentThread())) {}}public void unlock() {this.owner = null;}
}

在这里插入图片描述
在这个方法中,owner变量如果是null,那么此时就是未加锁状态,那么CAS方法就返回true,取反则为false,退出循环,此时就是未加锁,但当owner这个变量不为null的时候调用CAS方法的线程就会将该对象的引用赋值给this.owenr,这个操作是原子的,所以不会有线程安全问题,从侧面就可以体现相当于对这个线程加锁,从此实现了锁的功能。

3.3CAS的ABA问题

3.3.1ABA问题

假设此时我有两个线程分别为t1和t2线程,还有一个共享变量num,此时t1线程想要通过CAS编码的形式把num原来的值A改为C,但是在这个操作之中,t2线程将num中的值从A改为B,又从B改为A,但是在这期间,t1线程不知道。

3.3.2ABA引起的BUG

比如,有一个cs中的悍匪玩家刚好现在余额还有17元买一个钥匙开个箱子,在购买的过程中,因为网络的波动,他按了两次购买键,导致启动了两个线程去完成这个任务,那么t1线程在购买的时候,t2线程在等待阻塞,t1线程完成了购买获得了一把钥匙,但在t2线程执行前刚好另一个ct好友给这位悍匪玩家充值了17元,导致t2线程在执行的时候发现余额中还有17元,则又帮悍匪玩家买了一把,此时就出现了bug,这个时候买了两把钥匙就是ABA问题引起的。

3.3.3如何避免由ABA问题引起的BUG

在要修改的值加入一个版本号,在CAS比较数据的时候比较当前值和之前要修改的值,也要比较版本号是否相同
CAS操作在读取之前要修改的值的同时,也要读取版本号
真正到修改的时候:
如果当前读的版本号与之前要修改的版本号相同,则修改数据并且修改版本号
如果当前读的版本号与之前要修改的版本号不相同,则视为修改失败(可以认为该数据被修改过)
将这个思路带到悍匪玩家买钥匙的案例中:

  • 购买钥匙需要17余额,t1和t2线程获取的余额是17,版本号都是1
  • t1线程购买成功之后,余额变为0,版本号变为2,此时t2线程再阻塞等待
  • 在t2线程执行前,悍匪玩家的好友ct兄弟为其充值了17元余额,此时账户余额又变为17,但此时版本号为3
  • 到t2线程执行的时候,发现余额是17,和之前读到的余额是一样,但是版本号不一样,第一次读的是1,但现在读的是3,版本号不同,则可以视为操作失败

4.java.util.concurrent常见类

4.1Callable接口

这个接口里有个叫call()方法,这个方法与Runnable接口中的run()方法其实大同小异,只是前者有个返回值
在Java中,Thread类的构造方法不直接接受一个Callable对象作为参数。,则需要另一个类来作为一个媒介,FutureTask作为一个媒介。

public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable = new Callable<Integer>() {int sum = 0;@Overridepublic Integer call() throws Exception {for (int i = 1; i < 1000; i++) {sum += i;}return sum;}};FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread thread = new Thread(futureTask);thread.start();thread.join();System.out.println("sum = " + futureTask.get());
}

4.2ReentrantLock类

4.2.1发音

ReentrantLock

4.2.2ReentrantLock的关键特性与功能

  1. ReentrantLock提供了公平锁的实现
  2. ReentrantLock提供了tryLock操作,该操作会立即返回,是否获取到锁,这对于避免死锁和实现超时机制非常有用。
  3. ReentrantLock搭配了Condition类完成等待通知,Condition比wait和notify更强点,Condition可以指定阻塞线程唤醒

4.3Semaphore类——信号量

信号量就是一个计数器,计系统资源的个数。
在底层中对信号量的两个基本操作分别为P操作和V操作
P操作——申请资源
V操作——释放资源
在java中JVM将这两个操作分别封装成acquire(申请资源),release(释放资源)

相关文章:

【JavaEE】多线程进阶

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; 文章目录 1.锁策略1.1悲观锁和乐观锁1.2重量级锁和轻量级锁1.3自旋锁和挂起等待锁1.4可…...

大模型LLM面试常见算法题-包括Attention和Transformer常见面试题

大模型&#xff1a; 位置编码有哪些&#xff1f; 介绍LoRA与QLoRA RAG和微调的区别是什么&#xff1f; 哪些因素会导致LLM的偏见&#xff1f; 什么是思维链&#xff08;CoT&#xff09;提示&#xff1f; Tokenizer的实现方法及原理 解释一下大模型的涌现能力&#xff1f;…...

90元搭建渗透/攻防利器盒子!【硬件篇】

前言 以下内容请自行思考后进行实践。 使用场景 在某些情况下开软件进行IP代理很麻烦&#xff0c;并不能实现真正全局&#xff0c;而且还老容易忘记&#xff0c;那么为了在实景工作中&#xff0c;防止蓝队猴子封IP&#xff0c;此文正现。 正文 先说一下实验效果&#xff1…...

用vue2+elementUI封装手机端选择器picker组件,支持单选、多选、远程搜索多选

单选注意点&#xff1a; touchmove.prevent: 在 touchmove 事件上添加 .prevent 修饰符&#xff0c;以阻止默认的滚动行为。 handleTouchStart: 记录触摸开始的 Y 坐标和当前的 translateY 值。 handleTouchMove: 计算触摸移动的距离&#xff0c;并更新 translateY 值。 han…...

『古籍自有答案』古风H5案例赏析

「古籍自有答案」&#xff0c;一部由新京报与字节跳动公益联合打造的古风H5&#xff0c;以诗意盎然的开篇引领用户穿梭于千年文脉。 part1. 创意定位 "人生有惑问先贤&#xff0c;先贤答案存古籍"&#xff0c;在这里&#xff0c;每一个灵魂的探问&#xff0c;都能在…...

Laravel模型事件完全指南:触发应用程序的动态行为

标题&#xff1a;Laravel模型事件完全指南&#xff1a;触发应用程序的动态行为 在Laravel框架中&#xff0c;模型事件提供了一种优雅的方式来处理Eloquent模型生命周期中的各种关键时刻。通过监听和响应这些事件&#xff0c;开发者可以自动化许多常见的任务&#xff0c;如日志…...

hot100 |八、二叉树

1-leetcode94. 二叉树的中序遍历 注意&#xff1a;√ 递归方法已经很熟练了&#xff0c;两种不同的递归方式迭代法需要注意&#xff0c;zrm就遇到了要求迭代实现&#xff0c;前序遍历和后续遍历其实不难&#xff0c;中序遍历用的少&#xff0c;注意看一看 // 1.递归方法1Lis…...

Matlab协方差矩阵分解法生成随机场

Matlab协方差矩阵分解法生成随机场 相关系数矩阵 % function outcohesion(x,y,mu,theta) % end % xyload(F:\Research-OUC\基于机器许学习模型的海底斜坡可靠度研究\基于comsol的斜坡稳定性分析\comsol网格操作\grid_operate-matlab.mphtxt); % xxy(:,1); % yxy(:,2); Xlinspac…...

android 在清单文件中配置receiver,系统是何时会注册此广播接收者的?

在 Android 中&#xff0c;通过清单文件&#xff08;AndroidManifest.xml&#xff09;配置的广播接收器&#xff08;BroadcastReceiver&#xff09;&#xff0c;系统会在特定的时机自动注册这些广播接收器。以下是详细的说明&#xff1a; 静态注册的广播接收器 静态注册的广播…...

嵌入式硬件电路常用设计软件

目录 1. Cadence Allegro 2. PADS 3. Altium Designer 4. Multisim 5. Protues 1. Cadence Allegro 功能&#xff1a; Cadence Allegro是Cadence公司推出的先进PCB&#xff08;Printed Circuit Board&#xff0c;印刷电路板&#xff09;设计布线工具&#xff0c;也是目前…...

c#的List<T>的SelectMany 和Select

在C#中&#xff0c;List<T>&#xff08;以及任何实现了IEnumerable<T>的集合&#xff09;的Select和SelectMany扩展方法都是LINQ&#xff08;Language Integrated Query&#xff09;的一部分&#xff0c;用于对集合中的元素进行查询和转换。 尽管它们的作用有些相…...

69.WEB渗透测试-信息收集- WAF、框架组件识别(9)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;68.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;8&#xff09; 有无waf存在&am…...

ASCII码对照表(Matplotlib颜色对照表)

文章目录 1、简介1.1 颜色代码 2、Matplotlib库简介2.1 简介2.2 安装2.3 后端2.4 入门例子 3、Matplotlib库颜色3.1 概述3.2 颜色图的分类3.3 颜色格式表示3.4 内置颜色映射3.5 xkcd 颜色映射3.6 颜色命名表 4、Colorcet库5、颜色对照表结语 1、简介 1.1 颜色代码 颜色代码是…...

Mysql-常用函数及其用法总结

1、字符串函数 测试用例如下&#xff1a; 1.1 CONCAT() 将多个字符串连接成一个字符串。 SELECT CONCAT(first_name, , last_name) AS full_name FROM users; -- 期望结果&#xff1a;John Doe, Jane Smith, Michael Johnson 1.2 SUBSTRING() 提取子字符串 SELECT SUBSTR…...

【c++刷题笔记-数组】day29:452. 用最少数量的箭引爆气球、 435. 无重叠区间 、 763.划分字母区间

452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;先按照左边界排序&#xff0c;当前的左边界大于前一个的右边界的时候&#xff0c;表示没有覆盖所以需要一根箭&#xff0c;反之则要更新为最小的右边界 重点&#xff1a;是区间覆盖问题…...

【数据结构】链表带环问题分析及顺序表链表对比分析

【C语言】链表带环问题分析及顺序表链表对比分析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【C语言】链表带环问题分析及顺序表链表对比分析前言一.顺序表和链表对比1.1顺序表和链表的区别1.2缓存利用率&#…...

快速解决找不到krpt.dll,无法继续执行代码问题

对于那些遇到计算机开机出现由于无法找到krpt.dll&#xff0c;进而无法继续执行代码问题的用户。 krpt.dll是计算机系统中与DirectX紧密相关的重要文件&#xff0c;如果它出现问题&#xff0c;可能会对一些特定的软件或游戏的运行产生影响。实际上&#xff0c;我们有多种解决该…...

C# List、LinkedList、Dictionary性能对比

数据结构性能对比 List、LinkedList、Dictionary 1. ArrayList &#xff08;List&#xff1a;前传&#xff09; ArrayList 是一个特殊数组&#xff0c; 通过添加和删除元素就可以动态改变数组的长度。 ArrayList集合相对于数组的优点&#xff1a; 支持…...

【Spring Cloud】微服务的简单搭建

文章目录 &#x1f343;前言&#x1f384;开发环境安装&#x1f333;服务拆分的原则&#x1f6a9;单一职责原则&#x1f6a9;服务自治&#x1f6a9;单向依赖 &#x1f340;搭建案例介绍&#x1f334;数据准备&#x1f38b;工程搭建&#x1f6a9;构建父子工程&#x1f388;创建父…...

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...