JavaEE 09 锁策略

1.锁策略

1.1 乐观锁与悲观锁

其实前三个锁是同一种锁,只是站在不同的角度上去进行描述,此处的乐观与悲观其实是指在预测的角度上看会发生锁竞争的概率大小,概率大的则是悲观锁,概率小的则是乐观锁

乐观锁在加锁的时候就会做较少的事情,加锁的速度较快,但是消耗的cpu资源等也会增加,悲观锁在加锁的时候就会做很多事情来避免锁的冲突,从而加锁的时候做的事情就比较多,加锁的开销相对较小

1.2 轻量级锁与重量级锁

这里是从加锁的量级出发,本质上是和上面的悲观锁和乐观锁的意思差不多,意思是从结果的角度上看,轻量级的锁加锁开销小,重量级的锁加锁开销比较大

1.3 自旋锁与挂起等待锁

自旋锁是轻量级锁和乐观锁的一种典型实现方式,挂起等待锁是重量级锁的一种典型实现方式,自旋锁就是有一个while循环来一直判断是否需要加锁,加上锁了就跳出循环,加锁不成功就继续判断而不是阻塞,这就导致了一直消耗了系统的资源而没有做实事,所以说消耗了相对多的cpu资源

挂起等待锁则与他截然相反,挂起等待锁就需要内核调度器去参与操作了,所以要做的事情也就多了,所以需要获取到锁的时间也就多了

1.4 普通互斥锁与读写锁

普通互斥锁类似于Synchronized,有加锁和解锁两个动作

读写锁则是两种锁

读锁和读锁之间不会有锁冲突

写锁和读锁之间会有锁冲突

写锁之间也会有锁冲突

总结:一个线程加读锁的时候,另一个线程只能读不能写

一个线程加写锁的时候,另一个线程不能写也不能读

这个要和MySQL中事务的隔离级别要分得开

MySQL中的脏读,不可重复读,幻读

我们以一个有一条数据的表为例,age=10

脏读:事务A修改age =20,没有提交事务,事务B读取到这条数据之后,事务A回滚了,此时B就读到了一条脏的数据

不可重复读:事务B读取到了age=10,此时事务A修改数据为20并提交事务,事务B又一次查询数据,查到的两条数据是不一样的,这就是不可重复读

幻读:事务B查询到一条数据,此时事务A又增加一条数据,此时事务B再次查询就是两条数据,这就称为幻读

不可重复读和脏读之间的区别是:不可重复读读取的事务是已经提交的

1.5 公平锁与非公平锁

与之前介绍的线程饿死有一定的联系

这里的公平指的是先到先得,只要线程释放锁,第一个等待的线程可以率先拿到锁,就不会出现持有锁,释放锁,这样的循环持有的状态,导致其他线程没办法做事情

这就需要引入一个数据结构来实现先到先得这种特点

java原生的锁其实就是非公平锁,靠抢占式执行.

1.6 可重入锁与不可重入锁

我们之前说过,Synchronized就是一个可重入锁,就是针对一个线程,不断用这个锁加锁很多次,可重入锁不会出现问题,因为可重入锁只是增加了计数器,实际上仍然是只加了一层锁结构,而可重入锁就可能出现死锁的情况

2.Synchronized的锁优化策略

我们都说Synchronized有自适应的效果,能够根据锁冲突状态确定自己是什么类型的锁,那么到底是怎么回事呢??咱们慢慢说

Synchronized锁其实有三种状态,根据情况来逐级递增,注意这里的锁级别是不可降级的

1.偏向锁状态(假设没线程来竞争锁)

这里的核心思想就是懒汉模式的思想,用的时候再创建,能不加锁就不加锁,所谓的偏向锁,就是给线程加上一个非常轻量级的标记,如果没有人来竞争锁,就直接省略这样的加锁的操作,有的话则升级为轻量锁

2.轻量级锁状态(假设竞争较小)

此处的实现就是自旋锁,优点是可以第一时间拿到锁,缺点是比较消耗cpu资源

与此同时Synchronized也会计算锁竞争的激烈程度,从而来判断是否需要升级到重量级锁

对于轻量级锁来说,假设竞争这个锁的线程很多,那么大多数线程此刻就处自旋的状态,此刻就比较消耗cpu资源

3.重量级锁状态(假设竞争很大)

此时拿不到锁的线程就不会选择去自旋了,而是直接阻塞等待,直接让出cpu,当线程释放之后就会随机分配一个线程来持有这个锁

4.锁消除策略

Synchronized会自动判断线程加上的锁是否有效,在编译期间,如果判断无效就会自动把这个锁给干掉,比如说这里没有涉及到多个线程对成员变量的修改等等

5.锁粗化

会将多个细粒度的锁,合并成一个粗粒度的锁,避免了重复加锁解锁的过程

3.CAS策略 (避免使用锁的另一种解决线程安全问题的策略)

全称叫做compare and swap 就是比较和交换,其实是一个cpu指令

关于CAS的api都放在java的unsafe包内,也就是暂时不推荐去使用的

我们简单介绍一下它的观点与使用技巧

这里给出一段伪代码

address:内存中的地址

expectValue:寄存器1中的值

swapvalue:寄存器2中的值

比较内存中的值和寄存器1的值是否相同,相同则直接交换(赋值),返回一个true不相同则无事发生,返回一个false

java标准库也提供了很多原子类,保证了多线程操作一个数据是原子的,本质上就是基于cas的

我们这个时候用两个线程给她进行自增50000次就会获取到正确的结果,而不会出现线程安全问题了

原始标准库里的代码略显复杂,这里我们使用简化版本的进行说明

这里的一次自增操作是先拿到旧数据,然后使用cas进行操作,如果判断相等则直接写入内存,不相等则更新一下目前的旧值为内存中的最新值,从而进行自增,这里就不会出现线程安全问题了

如有问题,希望大家多多指正 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

crmeb v5自动生成代码报错(adminInfo方法或404路由不存在的问题)

404 现象 调试器中出现了404 , 那肯定是路由出了问题,也就是说,crmeb 为我们生成的路由没有对应的加载上,先来看一下, 自动代码为我们生成的路由是什么样子的 所以有一种最简单的解决办法,就是 把 新生成的路由文件从子目录中挪出一级来,就可以解决404的问题了 下面来说…

python学习:浅拷贝与深拷贝详解

copy 一、 & is二、浅拷贝 & 深拷贝(一)、浅拷贝(二)、深拷贝 三、问题 一、’ ’ & ‘is’ ’ 和is是python对象比较常用的两种方式,简单来说,‘ ‘操作符比较对象之间的值是否相等,如 a b 而’is’操作符比较的是对象的身份标识是否相等,即它们是否是同一个…

「玩转 TableAgent 数据智能分析」实战数据分析演练

文章目录 前言TableAgent 功能亮点人人都是数据分析师融合创新应用的新成果 TableAgent 使用介绍登陆功能介绍申请认证 实战数据集分析一导入 CSV 文件数据发起提问TableAgent 应答结果贴切的服务推荐问题提问 实战数据集分析二分析结果分析哪个城市的未来人口最多 总结 TableA…

linux高级管理——访问MYSQL数据库

一、认识数据库系统: MySQL数据库系统也是一个典型的C/S(客户端/服务器)架构的应用,要访问MySQL数据库需要使用专门的客户端软件。在Linux系统中,最简单、易用的MySQL客户端软件是其自带的mysql命令工具。 1.登录到My…

光伏开发设计施工一体化系统都有哪些功能?

随着全球对可再生能源的需求不断增加,光伏行业得到了快速发展。同时也面临着一些挑战,例如初始投资成本高、需要大量土地和水资源等。鹧鸪云光伏与储能软件利用技术创新,促进光伏行业数字化升级。 一、智能测算 1.投融资表:采用…

【FPGA/verilog -入门学习6】verilog频率计数器

需求 在使能信号控制下,计算输入脉冲的每两个上升沿之间的时钟周期数并输出,即输出脉冲频率的计数值 输入信号 周期性脉冲信号:需要做检测的脉冲频率信号 使能信号:高电平进行频率计数,低电平清零计数器 输出信号 计数…

bootstrap:下拉菜单

<!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>下拉菜单DEMO</title> <link rel"stylesheet" type"text/css" href"/cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css"…

TCP/IP详解——网络基本概念

文章目录 一、网络基本概念1. OSI 7层模型1.1 每层对应的协议1.2 每层涉及的设备1.2.1 物理层设备1.2.2 数据链路层设备1.2.3 网络层设备1.2.4 传输层设备1.2.5 交换机和路由器的应用1.2.6 问题 2. TCP/IP 4层模型3. 物理层传输介质3.1 冲突域 4. 数据链路层4.1 以太网帧结构4.…

​flutter 代码混淆

Flutter 应用混淆&#xff1a;Flutter 应用的混淆非常简单&#xff0c;只需要在构建 release 版应用时结合使用 --obfuscate 和 --split-debug-info 这两个参数即可。–obfuscate --split-debug-info 用来指定输出调试文件的位置&#xff0c;该命令会生成一个符号映射表。目前支…

mysql字段设计规范:使用unsigned(无符号的)存储非负值

如果一个字段存储的是数值&#xff0c;并且是非负数&#xff0c;要设置为unsigned&#xff08;无符号的&#xff09;。 例如&#xff1a; 备注&#xff1a;对于类型是 FLOAT、 DOUBLE和 DECIMAL的&#xff0c;UNSIGNED属性已经废弃了&#xff0c;可能在mysql的未来某个版本去…

C#学习笔记 - C#基础知识 - C#从入门到放弃

C# 第1节 C# 简单介绍1.1 C# 是什么1.2 C# 强大的编程功能1.3 C# 发展史1.4 C#与Java区别 第2节 C#程序结构2.1 Hello world2.2 C# 结构解析 第3节 C#基本语法3.1 第1节 C# 简单介绍 1.1 C# 是什么 C# 的发音为“C Sharp”&#xff0c;是一门由微软开发并获得了 ECMA&#xf…

Godot导出Android包报错:无效的包名称

问题描述 使用Godot为项目导出Android平台包时报错&#xff0c;提示&#xff1a;“无效的包名称&#xff1a;项目名称不符合包名格式的要求。请显式指定包名。” 解决办法 修改导出配置项“包->唯一名称”。 该项缺省值“org.godotengine.$genname”不能直接使用&#x…

Java版本+鸿鹄企业电子招投标系统源代码+支持二开+Spring cloud +鸿鹄电子招投标系统

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。为了符合国家电子招投标法律法规及相关规范&#xff0c;…

Debian openmediavault 自建Nas系统共享,raid5与btrfs文件系统无损原数据扩容

一、适用环境 1、企业自有物理专业服务器&#xff0c;一些敏感数据不外流时&#xff0c;使用openmediavault自建NAS系统&#xff1b; 2、在虚拟化环境中自建NAS系统&#xff0c;用于内网办公&#xff0c;或出差外网办公时&#xff0c;企业内的文件共享&#xff1b; 3、虚拟化环…

SD-WAN实现分公司与总部组网高效互联

随着企业的发展和扩张&#xff0c;对于分公司和总部的组网需求越来越多。然而企业分公司和总部之间的组网连接通常十分复杂&#xff0c;不仅消耗大量的预算&#xff0c;还耗费很长的部署时间。SD-WAN的出现使组网连接变得轻松、简单&#xff0c;提高了企业的网络连接效率和性能…

珠宝销售技巧培训之如何提升珠宝销售技巧

珠宝销售技巧培训之如何提升珠宝销售技巧 珠宝销售是一项需要技巧和策略的工作。在竞争激烈的珠宝市场中&#xff0c;销售人员需要不断提升自己的销售技巧&#xff0c;以吸引更多的客户并保持他们的忠诚度。本文将介绍一些提升珠宝销售技巧的方法&#xff0c;包括了解客户需求…

智能配电运维管理平台

智能配电运维管理平台是一种集成了自动化、智能化等技术手段的电力运维管理平台。依托智慧化工具-电易云&#xff0c;对配电系统的电力设备进行实时监控、数据分析和处理。该平台通常由数据采集、监控预警、计划维护、数据分析、决策支持等模块组成&#xff0c;能够实现电力设备…

如何处理PHP开发中的单元测试和自动化测试?

如何处理PHP开发中的单元测试和自动化测试&#xff0c;需要具体代码示例 随着软件开发行业的日益发展&#xff0c;单元测试和自动化测试成为了开发者们重视的环节。PHP作为一种广泛应用于Web开发的脚本语言&#xff0c;单元测试和自动化测试同样也在PHP开发中扮演着重要的角色…

冯诺依曼体系与操作系统的理解

目录 一.冯诺依曼体系结构 存储分级 为什么程序运行之前&#xff0c;必须加载到内存上&#xff1f; 二.操作系统 操作系统是什么&#xff1f; 为什么需要操作系统&#xff1f; 操作系统是如何管理软硬件资源&#xff1f; 一.冯诺依曼体系结构 我们常见的计算机&#xff…

docker安装rabbitmq并安装死信队列插件

环境 debian11 docker 20.10.22 rabbitmq 3.10.0 拉取镜像到本地 docker pull rabbitmq3.10.0 实例化 docker run -d --name rabbit -e RABBITMQ_DEFAULT_USERadmin -e RABBITMQ_DEFAULT_PASSadmin -p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:…