多线程相关(4)

线程安全-下

  • 使用层面锁优化
    • 减少锁的时间:
    • 减少锁的粒度:
    • 锁粗化:
    • 使用读写锁:
    • 使用CAS:
  • 系统层面锁优化
    • 自适应自旋锁
    • 锁消除
    • 锁升级
      • 偏向锁
      • 轻量级锁
      • 重量级锁
  • ThreadLocal原理
    • ThreadLocal简介
    • 原理
    • ThreadLocal内存泄漏
  • HashMap线程安全
    • 死循环造成 CPU 100%
  • String不可变原因

使用层面锁优化

减少锁的时间:

不需要同步执行的代码,能不放在同步快里面执行就不要放在同步快内,可以让锁尽快释放。

减少锁的粒度:

它的思想是将物理上的一个锁,拆成逻辑上的多个锁,增加并行度,从而降低锁竞争。它的思想也是用空间来换时间;java中很多数据结构都是采用这种方法提高并发操作的效率,比如:ConcurrentHashMap。
java中的ConcurrentHashMap在jdk1.8之前的版本,使用一个Segment 数组:Segment< K,V >[] segments。
Segment 继承自ReenTrantLock,所以每个Segment是个可重入锁,每个Segment 有一个HashEntry< K,V >数组用来存放数据,put操作时,先确定往哪个Segment放数据,只需要锁定这个Segment,执行put,其它的Segment不会被锁定;所以数组中有多少个Segment就允许同一时刻多少个线程存放数据,这样增加了并发能力。

锁粗化:

大部分情况下我们是要让锁的粒度最小化,锁的粗化则是要增大锁的粒度;
假如有一个循环,循环内的操作需要加锁,我们应该把锁放到循环外面,否则每次进出循环,都进出一次临界区,效率是非常差的。

使用读写锁:

ReentrantReadWriteLock 是一个读写锁,读操作加读锁,可并发读,写操作使用写锁,只能单线程写。

使用CAS:

如果需要同步的操作执行速度非常快,并且线程竞争并不激烈,这时候使用cas效率会更高,因为加锁会导致线程的上下文切换,如果上下文切换的耗时比同步操作本身更耗时,且线程对资源的竞争不激烈,使用volatile + cas操作会是非常高效的选择。

系统层面锁优化

自适应自旋锁

自旋锁可以避免等待竞争锁进入阻塞挂起状态被唤醒造成的内核态和用户态之间的切换的损耗,它们只需要等一等(自旋),但是如果锁被其他线程长时间占用,一直不释放CPU,死等会带来更多的性能开销;自旋次数默认值是10。
对上面自旋锁优化方式的进一步优化,它的自旋的次数不再固定,其自旋的次数由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定,这就解决了自旋锁带来的缺点。

锁消除

锁削除是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行削除。Netty中无锁化设计pipeline中channelhandler会进行锁消除的优化。

锁升级

偏向锁

如果线程已经占有这个锁,当他在次试图去获取这个锁的时候,他会已最快的方式去拿到这个锁,而不需要在进行一些 monitor 操作,因为在大部分情况下是没有竞争的,所以使用偏向锁是可以提高性能的

轻量级锁

竞争不激烈的情况下,通过CAS避免线程上下文切换,可以显著的提高性能

重量级锁

重量级锁的加锁、解锁过程造成的损耗是固定的,重量级锁适合于竞争激烈、高并发、同步块执行时间长的情况

ThreadLocal原理

ThreadLocal简介

通常情况下,我们创建的变量是可以被任何⼀个线程访问并修改的。如果想实现每⼀个线程都有⾃⼰的专属本地变量该如何解决呢?JDK中提供的 ThreadLocal 类正是为了解决这样的问题。类似操作系统中的TLAB

原理

首先 ThreadLocal 是一个泛型类,保证可以接受任何类型的对象。
因为一个线程内可以存在多个 ThreadLocal 对象,所以其实是 ThreadLocal 内部维护了一个 Map ,是 ThreadLocal 实现的一个叫做 ThreadLocalMap 的静态内部类。
最终的变量是放在了当前线程的 ThreadLocalMap 中,并不是存在 ThreadLocal 上,ThreadLocal 可以理解为只是 ThreadLocalMap 的封装,传递了变量值
我们使用的 get()、set() 方法其实都是调用了这个ThreadLocalMap类对应的 get()、set() 方法。

例如:
1.存储用户会话

private static final ThreadLocal threadSession = new ThreadLocal();

2.解决线程安全问题

private static ThreadLocal<SimpleDateFormat> format1 = new ThreadLocal<SimpleDateFormat>();

ThreadLocal内存泄漏

实际上 ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,⽽ value 是强引⽤
弱引用的特点是,如果这个对象持有弱引用,那么在下一次垃圾回收的时候必然会被清理掉。
所以如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候会被清理掉的,这样一来 ThreadLocalMap中使用这个 ThreadLocal 的 key 也会被清理掉。但是,value 是强引用,不会被清理,这样一来就会出现 key 为 null 的 value。假如我们不做任何措施的话,value 永远⽆法被GC 回收,如果线程长时间不被销毁,可能会产⽣内存泄露
ThreadLocal
ThreadLocalMap实现中已经考虑了这种情况,在调用 set()、get()、remove() 方法的时候,会清理掉 key 为 null 的记录。
如果说会出现内存泄漏,那只有在出现了 key 为 null 的记录后,没有手动调用 remove() 方法,并且之后也不再调用 get()、set()、remove() 方法的情况下
因此使⽤完ThreadLocal ⽅法后,最好⼿动调⽤ remove() ⽅法

HashMap线程安全

死循环造成 CPU 100%

HashMap 有可能会发生死循环并且造成 CPU 100% ,这种情况发生最主要的原因就是在扩容的时候,也就是内部新建新的 HashMap 的时候,扩容的逻辑会反转散列桶中的节点顺序,当有多个线程同时进行扩容的时候,由于 HashMap 并非线程安全的,所以如果两个线程同时反转的话,便可能形成一个循环,并且这种循环是链表的循环,相当于 A 节点指向 B 节点,B 节点又指回到 A 节点,这样一来,在下一次想要获取该 key 所对应的 value 的时候,便会在遍历链表的时候发生永远无法遍历结束的情况,也就发生 CPU 100% 的情况。
所以综上所述,HashMap 是线程不安全的,在多线程使用场景中推荐使用线程安全同时性能比较好的 ConcurrentHashMap。

String不可变原因

  1. 可以使用字符串常量池,多次创建同样的字符串会指向同一个内存地址;
  2. 可以很方便地用作 HashMap 的 key。通常建议把不可变对象作为 HashMap的 key;
  3. hashCode生成后就不会改变,使用时无需重新计算;
  4. 线程安全,因为具备不变性的对象一定是线程安全的。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

go interface{} 和string的转换问题

1.遇到的问题 问题来源于,我sql模版拼接遇到的问题。 首先&#xff0c;这样是没有问题的。 var qhx interface{} "qhx"s : qhx.(string)fmt.Println(s) 但是当我在这段代码里用:1.类型断言 var sqlStr "select * from tx_user where username %s" join…

代码随想录算法训练营第二十五天 | 216.组合总和III,17.电话号码的字母组合 [回溯篇]

代码随想录算法训练营第二十五天 LeetCode 216.组合总和III题目描述思路参考代码总结 LeetCode 17.电话号码的字母组合题目描述思路参考代码 LeetCode 216.组合总和III 题目链接&#xff1a;216.组合总和III 文章讲解&#xff1a;代码随想录#216.组合总和III 视频讲解&#xff…

opengl 学习纹理

一.纹理是什么&#xff1f; 纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c;它可以用来添加物体的细节&#xff1b;类似于图像一样&#xff0c;纹理也可以被用来储存大量的数据&#xff0c;这些数据可以发送到着色器上。 采样是指用纹理坐标来获取纹…

医学试纸条图像处理技术

医学试纸条图像处理是一个重要的领域&#xff0c;它涉及到从医学试纸条上提取和分析信息的各种技术。这里是一些常见的工作步骤&#xff1a; 一、图像预处理&#xff1a;在处理任何图像之前&#xff0c;通常需要进行预处理步骤&#xff0c;以改善图像质量并准备后续分析。这可…

VH6501采样点测试误差及影响因素分析(官方文档)

&#x1f4d9; 相关文章 &#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&…

挑战杯 基于情感分析的网络舆情热点分析系统

文章目录 0 前言1 课题背景2 数据处理3 文本情感分析3.1 情感分析-词库搭建3.2 文本情感分析实现3.3 建立情感倾向性分析模型 4 数据可视化工具4.1 django框架介绍4.2 ECharts 5 Django使用echarts进行可视化展示5.1 修改setting.py连接mysql数据库5.2 导入数据5.3 使用echarts…

解决vulhub漏洞环境下载慢卡死问题即解决docker-valhub漏洞环境下载慢的问题

解决vulhub环境下载慢/卡 当前环境为&#xff1a;ubuntu20 1.在 cd /etc/docker/目录下创建或修改daemon.json文件 sudo touch daemon.json编辑daemon.json文件 sudo vim daemon.json2.填写阿里云镜像地址&#xff1a; { "registry-mirrors":["https://6kx…

基础光学系列:(三)揭秘机器视觉中的光圈、焦距与景深的作用

​今天来聊聊成像原理、光圈、焦距和景深&#xff0c;这些概念在摄影、摄像以及机器视觉领域都非常重要。它们共同影响着成像设备捕捉图像的质量和特性。让我们一一解析这些概念以及它们如何在机器视觉行业中应用。 成像原理&#xff1a;怎样把外面的世界捕捉进来 想象一下&a…

Yolov8有效涨点:YOLOv8-AM,采用多种注意力模块提高检测精度,含代码,超详细

前言 2023 年,Ultralytics 推出了最新版本的 YOLO 模型。注意力机制是提高模型性能最热门的方法之一。 本次介绍的是YOLOv8-AM,它将注意力机制融入到原始的YOLOv8架构中。具体来说,我们分别采用四个注意力模块:卷积块注意力模块(CBAM)、全局注意力机制(GAM)、高效通道…

Buffer计算机基础fs模块path模块(day02)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈 一、Buffer 1.概念 Buffer中文译为【缓冲区】&#xff0c;是一个类似于Array的对象&#xff0c;用来表示固定长度的字节序列 简单理解&…

使用免费的L53巧解Freenom域名失效问题

进入2月份以来&#xff0c;不少小伙伴纷纷收到Freenom提供的域名失效&#xff0c;状态由正常变成了Pending。 失效后&#xff0c;域名无法使用&#xff0c;免费的午餐没有了&#xff0c;而现在域名的价格也是水涨船高&#xff0c;真是XXX。很多做外贸的小伙伴表示 难 啊&#x…

“一键焕发视频新生!炫酷色彩变幻特效,让您的创意视频大放异彩!“

在这个视频内容爆炸的时代&#xff0c;如何让您的视频作品脱颖而出&#xff0c;吸引观众的眼球&#xff1f;答案就是——色彩变幻特效&#xff01;通过为视频添加独特的色彩变幻效果&#xff0c;您可以轻松赋予作品无与伦比的魅力和视觉冲击力。 首先第一步&#xff0c;我们要进…

QWidget: Must construct a QApplication before a QWidget 13:25:48: 程序异常结束。

QWidget: Must construct a QApplication before a QWidget 13:25:48: 程序异常结束。 你的插件是release&#xff0c;而你用了debug模式、

[NPUCTF2020]ezinclude ---不会编程的崽

做完这题&#xff0c;又get到一个新的知识点。上界面 源代码里有线索 secret是秘密值&#xff0c;name与pass应该是可以控制的变量。抓个包看看 发送与请求有hash值&#xff0c;没猜错应该是用来验证的。拿去爆破了&#xff0c;啥也没爆破出来。先传参 右边的hash值改变了。猜想…

注解开发总结

目录 注解开发定义bean纯注解开发bean作用范围与生命周期依赖注入——自动装配第三方 bean第三方 bean 管理第三方 bean 依赖注入 XML配置比对注解配置 注解开发定义bean 使用 Component 定义 bean &#xff0c; 括号里面可以认为是 id Component("bookDao") publi…

MATLAB环境下基于图像处理的视网膜图像血管分割

预防糖尿病对每个人的健康至关重要&#xff0c;而糖尿病的早期症状在眼底视网膜血管会有所体现&#xff0c;如静脉血管扩张、轻度弯曲等。高血压作为常见疾病&#xff0c;在中国有多达2.45亿的患者。高血压的病情也会在眼底视网膜血管上有所体现&#xff0c;如交叉压迫征等反映…

Spring篇----第四篇

系列文章目录 文章目录 系列文章目录前言一、区分构造函数注入和 setter 注入二、spring 中有多少种 IOC 容器?三、区分 BeanFactory 和 ApplicationContext。四、列举 IoC 的一些好处。前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大…

Stable Diffusion 3重磅发布

刚不久&#xff0c;Stability AI发布了Stable Diffusion 3.0&#xff0c;这一版本采用了与备受瞩目的爆火Sora相同的DiT架构。通过这一更新&#xff0c;画面质量、文字渲染以及对复杂对象的理解能力都得到了显著提升。由于这些改进&#xff0c;先前的技术Midjourney和DALL-E 3在…

金融知识分享系列之:五日线

金融知识分享系列之&#xff1a;五日线 一、股票均线二、五日线三、五日线加量能三、五日线案例四、五日线案例五、五日线案例六、五日线案例七、五日线案例八、五日线案例 一、股票均线 股票均线是一种用于平滑股票价格的指标。它是根据一段时间内的股票价格计算得出的平均值…

定时任务处理-Spring Task

目录 1 前言 2 cron表达式 2.1 相关概念的介绍 2.2 举个例子(白雪警告) 2.3 使用网站自动生成 3 Spring Task的使用 3.1 导入依赖坐标 3.2 开启任务调度 3.3 自定义定时任务类 1 前言 当我们需要处理一些定时任务的时候就需要用到我们的Spring Task&#xff0c;接下来…