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

[JAVAee]锁策略

目录

乐观锁与悲观锁

乐观锁

乐观锁的冲突检测

悲观锁

读锁与写锁

重量级锁与轻量级锁 

重量级锁

轻量级锁

自旋锁

公平锁与非公平锁

可重入锁与不可重入锁


乐观锁与悲观锁

乐观锁

在乐观锁中,假设数据并不会发生冲突,在正式提交数据时会对数据进行冲突检测,如果发生了冲突则会返回错误信息,将决定权交给用户

乐观锁的冲突检测

冲突检测是乐观锁的一个重要功能.

实现这个功能的方式主要是:引入一个版本号,每次线程中的工作内存进行操作后,版本号会相应的+1,只有在提交数据工作内存中的版本号大于主存中的版本号才能提交成功.

示例:

在乐观锁下两个线程分别进行+1操作

首先线程1先被调度,将n进行+1操作后版本号也+1.

线程1中的数据要拷贝到主存中,首先要看两者的版本号.线程1中的版本号大于主存中的版本号,可以写入数据.

 此时,线程2也进行+1操作,但线程2中的工作内存n还没有更新.

当线程2想要写入的时候,会发现自己的版本号没有大于主存中的版本号.

写入失败,主存中的数据就不会更新.

悲观锁

总是假设为最坏的情况,每次去拿数据的时候都会认为别人去修改.所以每次去拿数据的时候都会上锁,这样别人再想拿数据的时候就会阻塞.

对于synchronized来说,初始会使用"乐观锁",发现竞争比较激烈的时候才会自动转换到"悲观锁"

读锁与写锁

在多线程的环境下,数据的读取线程之间是不会互斥的,但读取线程与写入线程之间会互斥.

如果两种情景下,都使用同一把锁.就会产生极大的性能损耗.

为了解决这种情况,就有了读锁与写锁(readers-writer lock)

对于读操作与写操作

  • 线程之间的读操作,并不会有线程安全的问题,可以之间并发读取.
  • 线程之间的写操作,就会产生线程安全的问题.
  • 线程之间的读操作与写操作,会产生线程安全的问题.

 读写锁就可以把这些情况都区分开,降低性能的消耗.

在java标准库中,提供了ReentrantReadWriteLock类,其中实现了读锁写.

ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
readLock.lock();
readLock.unlock();ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
writeLock.lock();
writeLock.unlock();

其中:(互斥就是线程会进入阻塞状态)

  1. 读锁与读锁之间不互斥
  2. 写锁与写锁之间互斥
  3. 读锁与写锁之间互斥

读写锁适用于频繁读,但不频繁写的场景下.

重量级锁与轻量级锁 

锁的核心特性为:"原子性".

这种特性的来源,能追溯到CPU这种硬件提供的.

  • CPU 提供了 "原子操作指令".
  • 操作系统基于 CPU 的原子指令, 实现了 mutex 互斥锁.
  • JVM 基于操作系统提供的互斥锁, 实现了 synchronized 和 ReentrantLock 等关键字和类.

重量级锁

加锁机制依赖操作系统(内核态)提供mutex.

就会发生大量的内核态与用户态之间的转换即线程的调度

轻量级锁

加锁机制尽量不依赖于操作系统的mutex,而是在用户态中使用代码实现.如果无法实现,再去调用mutex.

可以减少内核态与用户态之间的转换

 synchronized初始为轻量级锁,在竞争激烈的时候才转换为重量级锁

自旋锁

线程在抢锁失败后会进入阻塞状态(放弃CPU,暂时停止运行).需要经过较久的时间才会被重新调度.

通常情况下,抢夺的锁很快就会被释放出来.就没必要进入阻塞(放弃CPU).

自旋锁就可以解决这种情况.

自旋锁在竞争锁失败后,会立即尝试获取锁,循环直到成功获取到锁.一旦锁被释放,很快就能够获取到.

自旋锁虽然能在锁被释放的第一时间获取到锁,但如果锁被占用的时间较长就会持续的消耗CPU的资源.

公平锁与非公平锁

  • 公平锁:遵守先来后到的顺序,先尝试获取锁的线程首先能占用到
  • 非公平锁:不遵守先来后到的顺序,随机调度

在操作系统中,锁的调度都是随机的.如果不加以任何限制,那么其就是一个非公平锁.

而实现公平锁,需要一个额外的数据结构来存储线程尝试获取锁的顺序.

synchronized是一个非公平锁

可重入锁与不可重入锁

可重入锁的字面意思是“可以重新进入的锁”,即允许同一个线程多次获取同一把锁.加锁后仍然可以进行递归操作重新获取锁而不会阻塞自己的锁就为可重入锁.(因为这个原因可重入锁也叫做递归锁)

synchronized是可重入锁
 

相关文章:

[JAVAee]锁策略

目录 乐观锁与悲观锁 乐观锁 乐观锁的冲突检测 悲观锁 读锁与写锁 重量级锁与轻量级锁 重量级锁 轻量级锁 自旋锁 公平锁与非公平锁 可重入锁与不可重入锁 乐观锁与悲观锁 乐观锁 在乐观锁中,假设数据并不会发生冲突,在正式提交数据时会对数据进行冲突检测,如果发…...

uni-app-使用tkiTree组件实现树形结构选择

前言 在实际开发中我们经常遇见树结构-比如楼层区域-组织架构-部门岗位-系统类型等情况 往往需要把这个树结构当成条件来查询数据,在PC端可以使用Tree,table,Treeselect等组件展示 在uni-app的内置组件中似乎没有提供这样组件来展示&#x…...

SQL-每日一题【1179. 重新格式化部门表】

题目 部门表 Department: 编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。 查询结果格式如下面的示例所示: 解题思路 1.题目要求我们重新格式化表,…...

GO语言语法结构

GO语言结构 包声明引入包函数变量语句 && 表达式注释 package main import "fmt" func main() {fmt.Println("Hello,World!") } 如这段代码块根据上面的语法结构进行逐行解释 第一行的 package main 是定义一个包名,必须在源文件…...

C++学习——模板

目录 🍉一:什么是模板 🍎二:普通模板的定义 🍍三:类模板的定义 🍌四:模板的实例化 🍇1.当普通模板定义存在可修改返回值产生的分歧 🍈2:类模板实例…...

二叉树的遍历(先序遍历,中序遍历,后序遍历)递归与非递归算法

目录 一、先序遍历题目链接1.递归2.非递归 二、中序遍历题目链接1.递归2.非递归 三、后序遍历题目链接1.递归2.非递归 一、先序遍历 先序遍历:先遍历一颗树的根节点,后遍历左子树,最后遍历右子树 先序遍历序列: 1 -> 2 -> 4…...

【LeetCode】516. 最长回文子序列

文章目录 1. 思路讲解1.1 创建dp表1.2 状态转移方程1.3 不需考虑边界问题 2. 整体代码 1. 思路讲解 1.1 创建dp表 此题采用动态规划的方法,创建一个二维dp表,dp[i][j]表示s[i, j]中最大回文子序列的长度。且我们人为规定 i 是一定小于等于 j 的。 1.2…...

Java 集合框架

Java 集合框架提供了一组接口和类,以实现各种数据结构和算法。 集合框架满足以下几个要求。 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。 该框架允许不同类型的集合…...

遇到多人协作,我们该用git如何应对?(版本二)

一、多人协作二 1.1多人协作 一般情况下,如果有多需求需要多人同时进行开发,是不会在一个分支上进行多人开发,而是一个需求或一个功能点就要创建一个feature 分支。 现在同时有两个需求需要你和你的小伙伴进行开发,那么你们俩便…...

Flutter iOS 集成使用 fluter boost

在 Flutter项目中集成完 flutter boost,并且已经使用了 flutter boost进行了路由管理,这时如果需要和iOS混合开发,这时就要到 原生端进行集成。 注意:之前建的项目必须是 Flutter module项目,并且原生项目和flutter m…...

node.js相关的npm包的集合

一、实用功能 1. qs 一个简单易用的字符串解析和格式化库 2.rxjs RxJS是一组模块化的库,用于使用 JavaScript 中的可观察集合和组合来组合异步和基于事件的程序。 3. mitt 微型 200b 功能事件发射器/发布订阅. 4.Underscore.js Underscore.js是一个用于 JavaScript…...

Android Ble蓝牙App(二)连接与发现服务

Ble蓝牙App(二)连接与发现服务 前言正文一、GATT回调二、连接和断连三、连接状态回调四、发现服务五、服务适配器六、显示服务七、源码 前言 在上一篇中我们进行扫描设备的处理,本文中进行连接和发现服务的数据处理,运行效果图如下…...

Android 自定义按钮(可滑动、点击)

按钮图片素材 https://download.csdn.net/download/Lan_Se_Tian_Ma/88151085 px 和 dp 转换工具类(Java) // px 和 dp 转换工具类 public class DensityUtil {/*** 根据手机的分辨率从 dip 的单位 转成为 px(像素)*/public static int dip2px(Conte…...

mac录屏怎么打开?很简单,让我来教你!

mac电脑作为一款广受欢迎的电脑系统,提供了多种方式来满足用户录屏的需求。无论您是要录制教学视频、制作演示文稿,还是记录游戏精彩瞬间,mac电脑都能帮助您实现这些目标。本文将为您介绍两种mac录屏的方法。通过本文的指导,您将能…...

Stable Diffusion AI绘画学习指南【插件安装设置】

插件安装的方式 可用列表方式安装,点开Extensions 选项卡,找到如下图,找到Available选项卡,点load from加载可用插件,在可用插件列表中找到要装的插件按install 按扭按装,安装完后(Apply and restart UI)应…...

APP开发中的性能优化:提升用户满意度的关键

APP开发中的性能优化是需要持续进行的,它不仅能够让用户体验到 APP的使用感受,还能在一定程度上提升用户的满意度,从而提升 APP的粘性和转化率。不过在实际开发中,很多 APP开发公司会存在性能优化上的问题,这就需要了解…...

Golang 切片 常用方法

文章目录 移除指定位置的元素查找元素的位置查找最大最小的元素去重随机打乱排序二维排序sort.Sort 排序 下面的方法省略一些校验,如数组越界等,且都采用泛型(要求go版本 > 1.18) 移除指定位置的元素 package mainimport ("fmt" )func Del…...

【Linux后端服务器开发】poll/epoll多路转接IO服务器

目录 一、poll原理 二、poll实现多路转接IO服务器 三、epoll函数接口 四、epoll的工作原理 五、epoll实现多路转接IO服务器 一、poll原理 poll函数接口 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);// pollfd结构 struct pollfd …...

【设计模式——学习笔记】23种设计模式——命令模式Command(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入介绍基础介绍登场角色 案例实现案例一实现 案例二介绍实现拓展 命令模式在JdbcTemplate源码中的应用总结文章说明 案例引入 有一套智能家电&#xff0c;其中有照明灯、风扇、冰箱、洗衣机&#xff0c;这些智能家电来自不同的厂家&#xff0c;我们不想针对每一…...

Rust中的高吞吐量流处理

本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库&#xff0c;还使用这些库实现了一个流处理程序。 最后&#xff0c;作者介绍了如何通过测量空闲和阻塞时间来优化流处理程序的性能&#xff0c;并将这些内容同步至…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...