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

3.10多线程

一.常见锁策略

1.悲观锁 vs乐观锁

体现在处理锁冲突的态度

①悲观锁:预期锁冲突的概率高

所以做的工作更多,付出的成本更多,更低效

②乐观锁:预期锁冲突的概率低

所以做的工作少,付出的成本更低,更搞笑

2.读写锁 vs 普通的互斥锁

①普通的互斥锁,只有两个操作 加锁和解锁

只有两个线程针对同一个对象加锁,就会产生互斥

②读写锁:有三个操作

针对读锁和读锁之间,是不存在互斥的关系--->因为多线程同时读一个变量,不会有线程安全的问题

读锁和写锁之间,写锁和写锁才需要互斥

而且很多场景中,都是读多写少

3.重量级锁 vs 轻量级锁

是为了处理锁冲突的结果

重量级锁 做了更多的事情,开销大,轻量级锁反之亦然

大多数情况下,悲观锁一般都是重量级锁,乐观锁一般都是轻量级锁

比如: 在使用的锁中,如果锁是基于内核的一些功能来实现的(比如调用了操作系统提供的mutex接口).一般认为这是重量级锁

如果锁是纯纯用户态实现的,一般认为这是轻量级锁,因为用户态的代码更可靠,也更高效

4.挂起等待锁 vs 自旋锁

①挂起等待锁:通过内核的一些机制来实现的.往往比较中 [重量级锁的一种典型实现]

②自旋锁 : 往往是通过用户态代码来实现的,往往比较轻,[轻量级锁的一种典型实现]\

5.公平锁 vs 非公平锁

公平锁:多个线程在等待一把锁的时候谁是先来的,谁就能先获取到这个锁(遵守先来后到

非公平锁:多个线程在等待一把锁的时候不遵守先来后到,每个等待的线程获取到锁的概率是均等的

对于操作系统来说->线程之间的调度是随机的(机会是均等的) .操作系统提供的mutex这个锁.就是属于非公平锁

6.可重入锁 vs 不可重入锁

可以嵌套加锁,就是可重入锁,会死锁的就是不可重入锁

7.synchronized(面试

1)即是一个乐观锁.也是一个悲观锁(根据锁竞争的激烈程度,自适应)

2)不是读写锁,只是一个普通互斥锁

3)既是一个轻量级锁,也是一个重量级锁,(根据锁竞争的激烈程度,自适应)

4)非公平锁 5)可重入锁

二.CAS

compare(比较) and swap(交换)

1.定义

CAS锁:拿着寄存器或者/某个内存的值和另外一个内存的值进行比较,如果值相同了,就交换

伪代码

CAS:提供一个单纯的CAS指令,通过这一条指令,就完成上述伪代码描述的过程

CAS指令:如果上述伪代码的过程只用一条做完,就是原子性,这个时候就是线程安全了

2.作用

1)基于CAS能够实现原子类

(java标准库里提供了一组原子性,针对常用的int.long,,int[]进行了封装,基于cas方式修改,并且线程安全

这段代码是不存线程安全的问题

基于CAS实现的++操作

因为这里既能保证线程安全,又能比synchronized高效

synchronized会涉及到锁的竞争,又要涉及线程的阻塞等待

这里的oldvalue变量,实际实际上可能使用一个寄存器来存的

这个赋值操作就相当于把数据从内存读到寄存器中(load

判定一下当前内存的值是不是和刚刚寄存器取到的值一直

如果判定成功,那就把value设为oldvalue+1.并返回true 循环结束

如果判定失败,继续下次循环,返回true;下次循环还是要先读一下value

这两行代码之间,很有可能有其他线程修改了value的值

为什么上述++操作线程安全

load

cas

2).基于CAS实现自旋锁

自旋锁是一个轻量级锁,也可以视为一个乐观锁

这把锁虽然没能够立即拿到,预期很快就能拿到(假设锁冲突不激烈)

3.ABA问题

1)定义

CAS中的关键就是先比较再交换

比较其实在比较当前值和旧值是否相同

把这两个值相同,就视为中间没有发生改变

但是这句话有漏洞,可能当前值和旧值相同的情况是因为变了然后又变回来了, 这就是ABA

2.案例

举例:ABA产生的BUG

假设小红账户余额 100 他想要取50

当按下取钱操作的时候,机器卡了一下,小红一紧张多按了一下取款

这就相当于 一次取钱操作 执行了两遍 (两个线程,并发的去执行这个取钱操作)

预期是只能取成功一次

如果基于CAS来实现的话

本来应该没问题

第二个线程再比较的时候就会发现,读到的100和原本的50不一样,就会不操作了

但是在取款的一瞬间,小红额度朋友给他转账了50.这个时候就会触发的ABA问题

这个时候第二个线程就会发现还是100.于是又扣了50

3)解决方法

引入版本号

这个版本号只能变大,修改变量的时候,比较的不是变量而是比较版本号

当引入版本号以后,t2再次尝试进行这里的比较版本操作

就会发现版本的旧值和当前的值并不匹配,就直接放弃修改

或者加入时间戳

看当前读到的内存改变的时间戳有没有变化

三.synchronized锁优化机制

只考虑1.8情况

1.锁膨胀/锁升级

体现了synchronized能够"自适应"这样的能力

偏向锁:并不是真的加锁,只是做了个标记.带来的好处就是后续没有竞争额时候,就避免了加锁解锁的开销

比如在大学校园里,大家都很讲素质,所以我的自行车都不锁->我只是在上面刻了我的名字做个标记

但是有一天好几个人的自行车都丢了,.开始有竞争的现象.我就开始加锁.进入轻量级锁

2.锁粗化/锁细化

此处的粗细指的是"锁的粒度"---->加锁代码涉及到的范围,范围越大,就认为锁的粒度越粗.反之亦然

锁粒度细 并发高

锁粒度粗.加锁解锁的开销就小

但是编译器会优化,如果某个地方代码所太细了,就会进行自动粗化

如果加锁之间间隔少(中间的代码少) 就很可能触发这个优化

比如:我给老师打电话,让他帮我请假.然后又打电话说我要出校,然后紧接着又打电话说我想借钱

每次给老师打电话都是给老师加锁,老师都不能接其他人的电话,加锁解锁开销大 粒度太细

于是可以粗化,我一次性说完.再挂电话

3.锁消除

有时候不小心加锁了

编译器发现这个锁没必要就会自动消除

比如StringBuffer Vector 在标准库里都进行了加锁操作

如果在单线程用到了上述的类,编译器会自动解锁.

四.java中的JUC

JUC ------java.util.concurrent

concurrent 并发的

1.Callable

是一个interface 也是一种创建线程的方式

因为Runnable 不太适合让线程计算一个结果

而如果用Callable就比较容易

    public static void main1(String[] args) throws InterruptedException {Result result=new Result();Thread t=new Thread(){@Overridepublic void run() {int sum=0;for (int i = 0; i < 100; i++) {sum+=i;}synchronized (result.locker){result.sum=sum;//如果不加锁额度话,这是一个写操作,可能会导致线程不安全的情况,需要加锁result.locker.notify();}}};t.start();synchronized (result.locker){while(result.sum==0){result.locker.wait();}}//加锁,直到赋值了才可以唤醒才可以往下执行System.out.println(result.sum);//这里还需要创建一个实例让他们的sum互相传}
    public static void main2(String[] args) {//构建一个类来描述任务Callable<Integer> callable=new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum=0;for (int i = 0; i < 100; i++) {sum+=i;}return sum;}};//因为线程的构造方法不能识别callable 需要创建一个类来识别,FutureTask<Integer> task=new FutureTask<>(callable);Thread thread=new Thread(task);thread.start();//凭借task能执行//如果线程里的任务没执行完,task.get(就会一直阻塞,直到任务完成try {System.out.println(task.get());} catch (InterruptedException e) {e.printStackTrace();//这是任务没执行完阻塞} catch (ExecutionException e) {e.printStackTrace();//这是任务出错执行}}

2.ReentrantLock

可重入锁,注意synchronized也是可重入锁

1)基础用法

lock()

unlock()

把加锁和解锁两个操作给分开了

这中分开额度做法不太好,容易出现死锁

当出现多个线程竞争同一把锁的时候就会阻塞

2)与synchronized区别(面试)

1.synchronized是一个关键字(背后的逻辑是由JVM实现的也就是c++代码)

ReentrantLock是标准库里的一个类 背后的逻辑是java代码写的

2,synchronized不需要手动释放锁,出代码块,锁自动释放,

ReentrantLock必须要手动释放锁,要谨防忘记释放

3.synchronized是一个非公平锁

ReentrantLock提供了非公平锁和非公平锁 在构造方法中,指定参数来 默认是false

4.synchronized如果竞争锁额度时候失败,就会阻塞等待

ReentrantLock不仅可以阻塞等待,还可以trylock 失败了直接返回

5.synchronized衍生出来的等待机制,是wait notify 功能是相对有限的

ReentrantLock衍生出来的等待机制,是Condition.功能比较丰富

3.Semaphore

信号量 是一个更广义的锁

是锁里的一种特殊情况,叫做二元信号量

这个牌子就是信号量,描述了可用资源的个数

每次申请一个可用资源,计数器就-1(也就是P操作 ->acquire 申请

每次释放一个可用资源 计数器就+1 也就是V操作 ->release 释放

当信号量的计数为0 再次进行p操作,就会阻塞等待

锁就可以视为二元信号量.可用资源就一个,计数器的取值非0即1

4.CountDownLatch

终点线

countdown 给每个线程里面调用就表示到达终点

await 给等待线程去调用 所有任务都到达终点了.awit就阻塞返回 就表示任务完成

当所有的选手都冲过终点才认为是比赛结束

多线程下载

    public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch=new CountDownLatch(10);//表示有10个选手for (int i = 0; i < 10; i++) {Thread t =new Thread(()->{try {Thread.sleep(3000);System.out.println(Thread.currentThread().getName()+"已到达");countDownLatch.countDown();//记录次数} catch (InterruptedException e) {e.printStackTrace();}});t.start();}//当十个线程都执行完,await才停止阻塞countDownLatch.await();System.out.println("比赛结束");}

五.哈希表

HashMap本身是线程不安全的

1.HashTable->推荐

2.ConcurrentHashMap->不推荐

针对this加锁,只要有多个线程来访问HashTable,就会加锁

假设员工想请假,就得当面来申请,他好签字

由于公司里的人很多,很多人都要请假,这个时候大家都在老板门口排队,非常不方便

每个HashTable都只有一把锁

解决方法

ConcurrentHashMap

每个链表头加锁

1.面试问题-CconcurrentHashMap和HashTable的关系

1.ConcurrentHashTable只是减少了锁冲突,就让锁加到每个链表的头节点

2,ConcurrentHashMap只是针对写操作 读操作没加锁

3,ConcurrentHashMap广泛使用CAS,

4,ConcurrentHashMap针对扩容,巧妙的化整为零

相关文章:

3.10多线程

一.常见锁策略1.悲观锁 vs乐观锁体现在处理锁冲突的态度①悲观锁:预期锁冲突的概率高所以做的工作更多,付出的成本更多,更低效②乐观锁:预期锁冲突的概率低所以做的工作少,付出的成本更低,更搞笑2.读写锁 vs 普通的互斥锁①普通的互斥锁,只有两个操作 加锁和解锁只有两个线程针…...

缓存双写一致性之更新策略探讨

问题由来 数据redis和MySQL都要有一份&#xff0c;如何保证两边的一致性。 如果redis中有数据&#xff1a;需要和数据库中的值相同如果redis中没有数据&#xff1a;数据库中的值是最新值&#xff0c;且准备会写redis 缓存操作分类 自读缓存读写缓存&#xff1a; &#xff0…...

scala高级函数快速掌握

scala高级函数一.函数至简原则二.匿名的简化原则三.高阶函数四.柯里化和闭包五.递归六.抽象控制七.惰性加载&#x1f525;函数对于scala&#xff08;函数式编程语言&#xff09;来说非常重要&#xff0c;大家一定要学明白&#xff0c;加油&#xff01;&#xff01;&#xff01;…...

手写模拟SpringMvc源码

MVC框架MVC是一种设计模式&#xff08;设计模式就是日常开发中编写代码的一种好的方法和经验的总结&#xff09;。模型&#xff08;model&#xff09;-视图&#xff08;view&#xff09;-控制器&#xff08;controller&#xff09;&#xff0c;三层架构的设计模式。用于实现前端…...

五分钟了解JumpServer V2.* 与 v3 的区别

一、升级注意项 1、梳理数据。JumpServer V3 去除了系统用户功能&#xff0c;将资产与资产直接绑定。当一个资产名下有多个同名账号&#xff0c;例如两个root用户时&#xff0c;升级后会自动合并最后一个root&#xff0c;不会同步其他root用户。升级前需保证每一个资产只拥有一…...

用友开发者中心应用构建实践指引!

基于 iuap 技术底座&#xff0c;用友开发者中心致力于为企业和开发者提供一站式技术服务&#xff0c;让人人都能轻松构建企业级应用。 本文以人力资源领域常用的应聘人员信息登记与分析功能为例&#xff0c;详细介绍如何在用友开发者中心使用 YonBuilder 进行应用构建。 功能…...

snap使用interface:content的基础例子

snap做包还在学习阶段&#xff0c;官网文档可查看&#xff1a;The content interface | Snapcraft documentation该例子由publiser和consumer两部分组成&#xff0c;一个提供一个只读的数据区&#xff0c;一个来进行读取其中的信息&#xff0c;这样就完成了content的交互。publ…...

蓝桥杯刷题第七天

第一题&#xff1a;三角回文数问题描述对于正整数 n, 如果存在正整数 k 使得2n123⋯k2k(k1), 则 n 称为三角数。例如, 66066 是一个三角数, 因为 66066123⋯363。如果一个整数从左到右读出所有数位上的数字, 与从右到左读出所有数位 上的数字是一样的, 则称这个数为回文数。例如…...

FinOps首次超越安全成为企业头等大事|云计算趋势报告

随着云计算在过去十年中的广泛应用&#xff0c;云计算用户所面临的一个持续不变的趋势是&#xff1a;安全一直是用户面临的首要挑战。然而&#xff0c;这种情况正在发生转变。 知名IT软件企业 Flexera 对云计算决策者进行年度调研已经持续12年&#xff0c;而今年安全问题首次…...

【深度强化学习】(3) Policy Gradients 模型解析,附Pytorch完整代码

大家好&#xff0c;今天和各位分享一下基于策略的深度强化学习方法&#xff0c;策略梯度法是对策略进行建模&#xff0c;然后通过梯度上升更新策略网络的参数。我们使用了 OpenAI 的 gym 库&#xff0c;基于策略梯度法完成了一个小游戏。完整代码可以从我的 GitHub 中获得&…...

Windows基于Nginx搭建RTMP流媒体服务器(附带所有组件下载地址及验证方法)

RTMP服务时常用于直播时提供拉流推流传输数据的一种服务。前段时间由于朋友想搭建一套直播时提供稳定数据传输的服务器&#xff0c;所以就研究了一下如何搭建及使用。 1、下载nginx 首先我们要知道一般nginx不能直接配置rtmp服务&#xff0c;在Windows系统上需要特殊nginx版本…...

交流电机驱动器中的隔离电压感应

汽车和工业终端设备&#xff0c;如电机驱动器、串式逆变器和机载充电器&#xff0c;在高电压下运行&#xff0c;不能安全地与人直接互动。隔离电压测量通过保护人类免受高压电路执行一个功能的影响&#xff0c;有助于优化操作和确保使用的安全性。 设计用于高性能&#xff0c;隔…...

爬取知乎问题答案

参考博客&#xff1a;基于Python知乎回答爬虫 jieba关键字统计可视化_知乎爬虫搜索关键词_菠萝柚王子的博客-CSDN博客 1、安装依赖包 import numpy import requests import certifi from PIL import Image from lxml import etree import jieba from wordcloud import WordClo…...

通用智能理论

将智能定义为解决矛盾的能力&#xff0c;用解决矛盾的概率提升来评估智能程度&#xff0c;以此为基础推导智能原理&#xff0c;建立一种新的通用智能理论。 1 前言 通用人工智能&#xff08;Artificial General Intelligence&#xff09;是人类长久以来的梦想。经历了一次次挫败…...

保姆级使用PyTorch训练与评估自己的MixMIM网络教程

文章目录前言0. 环境搭建&快速开始1. 数据集制作1.1 标签文件制作1.2 数据集划分1.3 数据集信息文件制作2. 修改参数文件3. 训练4. 评估5. 其他教程前言 项目地址&#xff1a;https://github.com/Fafa-DL/Awesome-Backbones 操作教程&#xff1a;https://www.bilibili.co…...

《百万在线 大型游戏服务端开发》前两章概念笔记

第1章 从角色走路说起 游戏网络通信的流程则是服务端先开启监听&#xff0c;等待客户端的连接&#xff0c;然后交互操作&#xff0c;最后断开。 套接字 每个Socket都包含网络连接中一端的信息。每个客户端需要一个Socket结构&#xff0c;服务端则需要N1个Socket结构&#xff…...

3BHE029110R0111 ABB

3BHE029110R0111 ABB变频器控制方式低压通用变频输出电压为380&#xff5e;650V&#xff0c;输出功率为0.75&#xff5e;400kW&#xff0c;工作频率为0&#xff5e;400Hz&#xff0c;它的主电路都采用交—直—交电路。其控制方式经历了以下四代。1U/fC的正弦脉宽调制&#xff0…...

实现防重复操作(JS与CSS)

实现防重复操作&#xff08;JS与CSS&#xff09; 一、前言 日常开发中我们经常会对按钮进行一个防重复点击的校验&#xff0c;这个通常使用节流函数来实现。在规定时间内只允许提交一次&#xff0c;可以有效的避免事件过于频繁的执行和重复提交操作&#xff0c;以及为服务器考…...

怎么合并或注销重复LinkedIn领英帐号?

您可能会发现您拥有多个领英帐户。如果您收到消息&#xff0c;提示您尝试使用的邮箱与另一个帐户已绑定&#xff0c;就表明您可能存在重复的领英帐户。如果您使用许多不同的邮箱地址&#xff0c;也可能会收到这样的提示。 领英精灵温馨提示: 目前&#xff0c;仅支持在 PC 端合并…...

Redis高频面试题汇总(中)

目录 1.什么是redis事务&#xff1f; 2.如何使用 Redis 事务&#xff1f; 3.Redis 事务为什么不支持原子性 4.Redis 事务支持持久性吗 5.Redis事务基于lua脚本的实现 6.Redis集群的主从复制模型是怎样的&#xff1f; 7.Redis集群中&#xff0c;主从复制的数据同步的步骤 …...

WSL2下USB串口设备‘失踪’?手把手教你找回/dev/ttyUSB0(以Quectel模块为例)

WSL2下USB串口设备消失的终极解决方案&#xff1a;从原理到实战 最近在WSL2环境下调试Quectel模块时&#xff0c;发现一个奇怪现象&#xff1a;lsusb明明能识别设备&#xff0c;但/dev/ttyUSB0却神秘失踪。这让我想起去年调试树莓派时遇到的类似问题&#xff0c;但WSL2的环境特…...

Realtek RTL8821CU无线网卡驱动解决方案 - Linux系统WiFi适配完美指南

Realtek RTL8821CU无线网卡驱动解决方案 - Linux系统WiFi适配完美指南 【免费下载链接】rtl8821CU Realtek RTL8811CU/RTL8821CU USB Wi-Fi adapter driver for Linux 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8821CU 你是否在Linux系统上使用Realtek RTL8821CU…...

**元宇宙经济中的智能合约开发实战:用Solidity构建去中心化资产交易系统**在元宇宙经济蓬勃发展的今

元宇宙经济中的智能合约开发实战&#xff1a;用Solidity构建去中心化资产交易系统 在元宇宙经济蓬勃发展的今天&#xff0c;数字资产的流通与确权成为核心议题。无论是虚拟土地、NFT艺术品还是游戏道具&#xff0c;背后都离不开区块链技术的支持。而智能合约正是连接现实世界资…...

基于博途1200PLC+HMI的六层三部电梯控制系统仿真程序

基于博途1200PLCHMI六层三部电梯控制系统仿真 程序&#xff1a; 1、任务&#xff1a;PLC.人机界面控制三部电梯集群运行 2、系统说明&#xff1a; 系统设有上呼、下呼、内呼、手动开关门、光幕、检修、故障、满载、等模拟模式控制&#xff0c; 系统共享厅外召唤信号&#xff0c…...

MIKE URBAN中污水处理厂如何进行概化

01 前言应用厂网一体化耦合模型研究水厂间调度和厂前溢流入河污染量等内容时&#xff0c;由于不需要关注污水处理厂内部的具体处理工艺&#xff0c;需要对污水处理厂的关键设施进行概化处理。02 水厂资料收集收集污水处理的工艺流程图和设施设计参数。依据厂网一体化模型的研究…...

Qwen3-TTS开源大模型实战:复古HUD界面下的AI语音创作工作流

Qwen3-TTS开源大模型实战&#xff1a;复古HUD界面下的AI语音创作工作流 1. 引言&#xff1a;当AI语音合成遇上复古游戏风 想象一下&#xff0c;你不再需要面对枯燥的音频参数调节界面&#xff0c;而是走进一个像素风的游戏世界。在这里&#xff0c;生成一段AI语音就像玩一款复…...

10分钟掌握全网资源下载神器:res-downloader从入门到精通

10分钟掌握全网资源下载神器&#xff1a;res-downloader从入门到精通 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 你是否遇…...

Qwen3-4B-Thinking开源镜像教程:Chainlit前端对接企业微信机器人

Qwen3-4B-Thinking开源镜像教程&#xff1a;Chainlit前端对接企业微信机器人 1. 引言&#xff1a;当大模型遇到企业级应用 想象一下这个场景&#xff1a;你刚部署好一个强大的AI模型&#xff0c;它能帮你写代码、分析问题、生成文档。但每次使用&#xff0c;你都得打开一个特…...

S32K312实战:用AUTOSAR Icu模块测量PWM占空比与周期(基于NXP MCAL与EB Tresos)

S32K312实战&#xff1a;AUTOSAR Icu模块精准测量PWM信号的工程实践 在汽车电子开发中&#xff0c;PWM信号的精确测量是ECU功能实现的基础环节。无论是发动机控制单元中的转速信号采集&#xff0c;还是车身电子中的执行器状态反馈&#xff0c;都需要对PWM信号的周期、占空比等参…...

当nodepad遇见AI:利用快马平台快速集成智能代码补全与文本润色功能

最近在折腾一个智能文本编辑器项目&#xff0c;想把AI能力集成到传统的文本编辑场景中。经过一番摸索&#xff0c;发现用InsCode(快马)平台可以快速实现这个想法&#xff0c;整个过程比想象中简单很多。这里记录下我的实践过程&#xff0c;分享给同样对AI辅助开发感兴趣的朋友。…...