当前位置: 首页 > 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;并将这些内容同步至…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

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

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

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...