Java中的锁

Java中的锁

乐观锁

乐观锁看待多线程访问同一资源的态度是乐观的,乐观锁假设线程访问同一资源时不会产生冲突^ 冲突,所以线程在访问资源时没有加锁同时也不会阻塞,但是乐观锁也是认为冲突^ 冲突还是有可能发生的,因此存在版本号和时间戳用于判断共享资源是否被其他线程所修改。乐观锁是乐观并发策略的一种具体实现。

  • 首先获取共享资源的版本号和时间戳
  • 在修改数据之前对版本号和时间戳进行判断
  • 如果不相等,表示其他线程修改了共享资源,需要重新获取版本号和时间戳并重新进行写操作
  • 如果相等则修改成功

悲观锁

乐观锁看待多线程访问同一资源的态度是悲观的,悲观锁假设线程访问同一资源时一定会产生冲突^ 冲突,所以线程对同一资源的写操作时会加锁,以此来解决写操作之间的冲突问题。悲观锁是悲观并发策略的一种具体实现。

乐观锁和悲观锁是两种不同的并发控制机制,用于处理多线程下共享数据的并发访问问题

可重入锁

当一个线程拥有锁对象时,需要访问另一个需要相同锁对象的资源时可以不用再次获取锁对象,如果不存在可重入锁,在某种情况下就会产生死锁问题。

在这里插入图片描述

如果不存在可重入锁,那么资源A想要访问资源B就需要先获取Test.class锁对象,但是由于锁对象此时并没有释放掉,因此就会出现死锁问题,于是可重入锁解决了因为这种情况而产生的死锁问题。

读写锁

读写锁中既有读锁也有写锁,读锁之间不是互斥的^ 互斥,写锁和读锁、写锁和写锁都是互斥的,当一个线程进行读操作时,需要获取读锁对象,如果此时存在其他线程获取读锁或者写锁,那么锁对象将获取不到。由于读锁之间是不互斥的,因此读写锁通常适用于读操作远远多于写操作的情况下,如果写操作远远多于读操作时,读写锁的性能可能还比不上互斥锁。

互斥锁只有两种状态,相比于互斥锁,读写锁的状态比较多,维护起来不方便。

分段锁

将共享资源的锁进行分段,减小锁的粒度,这样公共资源就有可能对多个线程同时进行访问,分段锁适用于共享资源较多的情况下,并且适用于读操作远远多于写操作的情况,如果写操作远远多于读操作,那么分段所的性能可能比不上互斥锁。

如果锁的粒度较小,当进行写操作时,可能对多个段产生影响,获取的锁对象要比互斥锁多,维护变得更加困难。

自旋锁

自旋锁是一种不断尝试获取锁对象的策略,其目的是尽量使得线程不阻塞,从而减少线程阻塞以及唤醒所带来的开销问题。适合获取锁对象时间较短的情况,如果获取锁对象的时间较长,就有可能导致多个线程等待并尝试获取锁对象,使得CPU开销较大。

共享锁

共享锁允许同一时刻有多个线程拥有共享锁的锁对象,并且共享锁只支持读取共享资源,不允许修改共享资源,例如读写锁中的读锁。

独占锁(排他锁)

独占锁就是互斥锁,同一时刻只有一个线程能够获取该锁的锁对象,独占锁在同一时刻只能存在一个线程对共享资源进行读取或者修改,例如读写锁中的写锁、悲观锁。

公平锁、非公平锁

公平锁

公平锁按照线程请求锁对象的顺序为线程分配锁对象,确保所有的线程都能在一定时间内获取到锁对象,是公平的。

非公平锁

非公平锁中当一个线程获取锁对象时,都会先尝试获取锁对象,如果失败了就将请求放入队列当中,如果获取锁对象成功后,就会执行获取到锁对象的线程,不论请求队列中是否存在其他请求,是一种非公平的获取方式,每个请求在放入队列之前都有尝试的机会。

锁状态

无锁状态

就是不加锁的状态

偏向锁状态

适用于长时间只有一个线程获取锁对象的情况,用于减少线程获取锁对象的开销,线程用完锁对象时不会释放锁对象,这样下次当前线程想要再次获取锁对象时就可以直接使用。当一个锁对象第一次被线程获取时,会记录其线程ID在对象头中,下一次线程获取锁对象时先判断线程ID是否相同,提高获取锁的速度。但是当存在其他线程需要获取锁对象时,JVM虚拟机会撤销偏向锁并将其转换为轻量级锁或者重量级锁,这个过程通常被称为锁的膨胀。

轻量级锁状态

轻量级锁锁的程度位于偏向锁和重量级锁中间,当线程获取轻量级锁对象失败后,线程不会阻塞,而是会采用CAS+自旋的方式尝试再次获取锁对象,直到自旋次数达到阈值,就会发生锁的膨胀,将锁升级为重量级锁。由于线程获取轻量级锁时会不断自旋,所以轻量级锁适用于锁竞争时间较短的情况(获取轻量级锁的线程不多),或者是说其他线程持有锁的时间较短的情况,不然线程不阻塞就会降低CPU性能。轻量级锁使用乐观并发策略,使用volatile+CAS算法来实现无锁的多线程变量同步。线程在获取轻量级锁时采取的是乐观并发策略。

重量级锁状态

当线程长时间获取不到轻量级锁对象时,就会发生锁的膨胀,将锁升级为重量级锁,当线程获取不到重量级锁对象时,线程就会被阻塞,直到线程被操作系统主动调用。

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

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

相关文章

浏览器中怎样查看前后端传值

路径:F12–>Network -->Fetch/XHR,选择一个接口地址。 在payload里面是前端发送给后端的参数。也即客户端发送给服务端的请求数据,即接口地址入参。 Preview和Response里都是后端返回给前端的。Preview是格式化过的,比较容易看。Resp…

初学python(一)

一、python的背景和前景 二、 python的一些小事项 1、在Java、C中,2 / 3 0,也就是整数 / 整数 整数,会把小数部分舍掉。而在python中2 / 3 0.66666.... 不会舍掉小数部分。 在编程语言中,浮点数遵循IEEE754标准,不…

[Linux]文件系统

[Linux]文件系统 文件系统是操作系统的一部分,负责组织、存储和管理存储在外部设备上的文件和目录,也就是操作系统管理外设中的文件的策略。本文讲解的是Ext2文件系统。Linux操作系统使用的就是Ext系列的文件系统。 文章目录 [Linux]文件系统了解磁盘结构…

【C++杂货铺】探索stack和queue的底层实现

文章目录 一、stack的介绍和使用1.1 stack的介绍1.2 stack的使用1.2.1 最小栈1.2.2 栈的压入、弹出序列1.2.3 逆波兰表达式求值1.2.4 用栈实现队列 二、queue的介绍和使用2.1 queue的介绍2.2 queue的使用2.2.1 二叉树的层序遍历 三、模拟实现3.1 stack模拟实现3.2 queue模拟实现…

Spine2D骨骼动画播放器 - 微信小程序版

Spine2D骨骼动画播放器 - 微信小程序版 简介平台支持 界面预览使用说明演示视频 版本笨笨的小目标(废话)参考资料测试文件百度盘分享 相关文档 简介 本播放器是SpinePlayer的微信小程序版。由于官方并没有提供现成的运行库,只能自己改造。 设…

Jobs Portal求职招聘系统源码v3.5版本

Jobs Portal求职招聘系统 是为求职者和公司发布职位而开发的交互式求职招聘源码。它使求职者能够发布简历、搜索工作、查看个人工作列表。 它将提供各种公司在网站上放置他们的职位空缺资料,并且还可以选择搜索候选人简历。 除此之外,还有一个管理模块供…

JAVASE---抽象类和接口

抽象类 抽象类的概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 抽象类语法 在…

振弦采集仪应用地铁隧道安全监测详细解决方案

振弦采集仪应用地铁隧道安全监测详细解决方案 随着城市化进程的不断加快,地铁作为一种高效、便捷、环保的交通方式已经成为现代城市不可或缺的一部分。因此,对地铁的安全性也越来越重视,一般二三线以上的城市在不断发展中,地铁做…

MIT的智慧,利用深度学习来解决了交通堵塞

导读大家都对交通阻塞深恶痛绝。除了让人头疼和错过约会之外,交通拥堵让美国的司机每年多花3000亿美元。 研究人员建议大家使用自动驾驶汽车,即使数量占比并不大,但也能大大改善交通拥堵情况。 Lex Fridman和他的MIT团队开发了一款模拟游戏来…

【大数据实训】用Hbase模拟电影搜索引擎(四)

博主介绍:✌全网粉丝6W,csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于大数据技术领域和毕业项目实战✌ 🍅文末获取项目联系🍅 《云计算与大数据处理》课程大作业评分表 项目考核内…

centos 端口被占用的快速排查方式

问题笔记 centos 端口被占用的快速排查方式 centos 端口被占用的快速排查方式 这里说一个我刚刚遇到的问题,解决步骤用来记录,方便以后自己查询。 nginx配置完index.html测试文件,发现一直显示的404页面。 我跑到服务器上想重启一下nginx …

使用Maven创建父子工程

📚目录 创建父工程创建子模块创建子模块示例创建认证模块(auth) 结束 创建父工程 选择空项目: 设置:项目名称,组件名称,版本号等 创建完成后的工程 因为我们需要设置这个工程为父工程所以不需要src下的所有文件 在pom…

认识JVM的内存模型

从上一节了解到整个JVM大的内存区域,分为线程共享的heap(堆),MethodArea(方法区),和线程独享的 The pc Register(程序计数器)、Java Virtual Machine Stacks(…

编程语言排行榜

以下是2023年的编程语言排行榜(按照流行度排序): Python:Python一直以来都是非常受欢迎的编程语言,它简洁、易读且功能强大。在数据科学、机器学习、人工智能等领域有广泛应用。 JavaScript:作为前端开发…

Lua03——开发环境搭建

1 安装开发插件 在 idea 或 vscode 中安装 lua 的开发插件 EmmyLua 2 创建工程 在 idea 中创建一个新的工程 工程的类型选择 lua 输入工程名及目标目录 在工程结构的SDK中设置lua在本地安装目录 在工程结构的modules中选择 lua 3 编写第一个lua程序 在工程下添加程序包&#…

Redis总结(一)

目录 Redis简介 为什么使用Redis作为MySQL的缓存? 高性能 高并发 Redis数据结构及其使用场景分别是什么? String(字符串) 内部实现 常用命令 普通字符串基本操作 批量设置 计数器(字符串内容为整数时使用&a…

[学习笔记]Node2Vec图神经网络论文精读

参考资料:https://www.bilibili.com/video/BV1BS4y1E7tf/?p12&spm_id_frompageDriver Node2vec简述 DeepWalk的缺点 用完全随机游走,训练节点嵌入向量,仅能反应相邻节点的社群相似信息,无法反映节点的功能角色相似信息。 …

集创北方ICN6202 MIPIDSI转LVDS转换芯片

集创北方ICN6202 1.描述: ICN6201是一个接收MIPIDSI输入和发送LVDS输出的桥接芯片。MIPIDSI最多支持4个车道,每个车道的最大运行频率为1Gbps;总最大输入带宽为4Gbps;并且还支持MIPI定义的ULPS(超低功耗状态&#xff…

c++通过tensorRT调用模型进行推理

模型来源: 算法工程师训练得到的onnx模型 c对模型的转换: 拿到onnx模型后,通过tensorRT将onnx模型转换为对应的engine模型,注意:训练用的tensorRT版本和c调用的tensorRT版本必须一致。 如何转换: 算法工…

机器人制作开源方案 | 桌面级机械臂--应用设计

本节内容将基于机器视觉带着大家进行应用实训。机器视觉是人工智能正在快速发展的一个分支,简单说来机器视觉就是用机器代替人眼来做测量和判断。机器视觉系统是通过机器视觉产品(即图像摄取装置,分CMOS和CCD两种)将被摄取目标转换…