java锁介绍

乐观锁

乐观地认为并发访问不会造成数据冲突,只在更新时检查是否有冲突。乐观锁和CAS的关系可以用“乐观锁是一种思想,CAS是一种具体的实现”来理解。

当使用CAS操作修改数据时,如果版本号不匹配或者其他线程已经修改了要操作的数据,CAS会返回失败。这时候,程序可以再次尝试CAS操作,也就是进行自旋重试,直到CAS操作成功。

因此,CAS操作已经内置了自旋重试的机制,避免了使用额外的自旋锁。

适用场景:适用于并发较低(高并发场景每次修改了去对比,还不如让加锁阻塞排队执行)、读多写少的场景,相信数据多数情况下不会发生冲突,只在更新时进行检查,以减少对共享资源的争用。

java中常见悲观锁实现:可以使用java.util.concurrent.atomic包中的原子类,比如AtomicInteger、AtomicLong等,来实现CAS操作。

mysql实现乐观锁:版本号、时间戳

悲观锁

悲观地认为并发访问会造成数据冲突,因此在访问共享资源之前就会进行加锁,确保同一时刻只有一个线程能够访问。

适用场景:适用于高并发写多的场景,通过加锁保护共享资源,确保并发访问时不会造成数据不一致性。

java中常见悲观锁实现:synchronized 关键字、ReentrantLock(可重入锁)

mysql中实现悲观锁:SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE

乐观锁ABA问题

ABA问题是在并发编程中一种常见的问题,特别是在使用乐观锁的情况下。它的发生主要是因为在执行CAS操作(比较并交换)时,数据的值发生了变化。

具体来说,假设有两个线程 T1 和 T2,初始时它们都读取了某个共享变量的数值为 A。然后 T1 首先将共享变量的值从 A 修改为了 B,然后再将其修改回 A,而线程 T2 在 T1 修改回 A 之前也对共享变量进行了修改(比如将 A 修改为了 C,然后再修改回 A)。在这种情况下,线程 T2 会错误地认为共享变量的值没有发生变化,因为它原始读取的值和最终值都是 A。这就是ABA问题的本质。

乐观锁通常使用CAS操作来实现,而CAS操作的基本思想是:读取当前内存值 A,比较 A 和预期值 B 是否相等,如果相等,则更新为新值 C;否则进行重试。在ABA问题中,CAS操作可能会由于共享变量的值从 A 变化为 B 再变化为 A,导致CAS操作在比较时误以为共享变量的值没有发生变化。

为了解决ABA问题,一种常见的方法是使用版本号(Version Numbering)或者时间戳(Timestamp)来标记共享变量的变化次数,每次修改共享变量时都更新版本号或时间戳,这样就能够避免因为共享变量的数值相同而导致的误判。另外,Java中的AtomicStampedReference类可以用于解决ABA问题,它通过引入一个标记来区分不同的修改次数,从而避免了传统CAS操作可能出现的ABA问题。

悲观锁 和 乐观锁 比较

相对而言,悲观锁适用于高并发,乐观锁适用于低并发
为什么乐观锁适用于并发量低:因为并发量高的时候,cas一直失败自旋没有任何意义,损耗性能,不如让cpu干其他的或者等待

锁升级

在 Java 中,锁升级是指在同步代码块中锁的状态发生改变的过程。这个过程包括偏向锁、轻量级锁和重量级锁三种状态的切换。
锁升级是JVM自动进行管理的。当JVM检测到多个线程对同步代码块的竞争时,会根据实际情况自动进行锁的升级。这种锁升级的机制是为了在多线程竞争情况下保证程序的安全和效率,以及在不同线程竞争程度下选择合适的锁状态,从而最大限度地提高并发性能。

偏向锁:

用于处理只有一个线程访问同步块的情况,减少不必要的竞争。
偏向锁需要在对象头中记录持有偏向锁的线程ID,避免重复的CAS操作。
适用于只有一个线程执行同步块的情况,从而减少不必要的同步操作。不用去加锁释放锁。

轻量级锁:

适用于短时间内只有少量线程竞争同步块的情况。
使用CAS操作尝试获取锁,避免了传统锁(互斥锁)的性能开销。
在少量线程竞争情况下,避免了传统锁的重量级化,提高了性能。

重量级锁:

当锁存在大量的线程竞争时会升级为重量级锁,采用传统的互斥锁实现。
保证了线程间数据同步和互斥访问,但性能开销相对较大。

偏向锁升级为轻量级锁:
当多个线程访问同步块时,偏向锁会升级为轻量级锁。这时,会使用CAS(Compare And Swap)操作来尝试获取锁,如果成功获取锁,则表示处于轻量级锁状态。

轻量级锁升级为重量级锁:
如果轻量级锁获取失败,就会升级为重量级锁。这时,会使用传统的互斥锁机制来确保线程间的互斥访问。

公平锁

公平锁则按照请求锁的顺序来获取锁,不允许插队,即等待时间最长的线程会优先获得锁。

非公平锁

非公平锁允许抢占,即允许在等待队列中的线程随机获取锁,synchronized 关键字是非公平锁

在 Java 中,ReentrantLock 是可重入锁的一种实现,通过使用 ReentrantLock 类,可以根据构造函数的不同参数选择是公平锁还是非公平锁。例如:

ReentrantLock fairLock = new ReentrantLock(true); // 创建一个公平锁
ReentrantLock unfairLock = new ReentrantLock(false); // 创建一个非公平锁

共享锁(Shared Lock):

允许多个事务同时获取对象的共享锁,可同时读取共享资源,但不允许进行修改。这种锁适用于读多写少的场景,可以提高并发读取的效率。

排他锁(Exclusive Lock):

排他锁是一种独占锁,它防止其他事务获取同一对象的共享或排他锁,确保只有一个事务能够对资源进行修改操作,其他事务需要等待该锁的释放。

可重入锁:

可重入锁是一种允许同一个线程多次获取同一把锁的锁。当线程第一次获取锁后,再次尝试获取该锁时,也会成功获取而不会被阻塞,这样可以避免死锁情况的发生。Java 中的 ReentrantLock 、synchronized 就是一种可重入锁的实现。
在这里插入图片描述

不可重入锁:

不可重入锁是一种不允许同一个线程多次获取同一把锁的锁。如果一个线程已经获取了该锁,再次尝试获取时会被阻塞,即使是同一个线程也不能再次获取这把锁,这可能会导致死锁情况。
在这里插入图片描述

单机锁:

单机锁是指在单个计算机或单个进程中控制对共享资源的访问的锁。常见的单机锁包括 synchronized 关键字、ReentrantLock 等。单机锁通常只在单个 JVM 内有效,不能跨越多个计算机或进程。 synchronized 关键字或 ReentrantLock 都是单机锁

分布式锁:

分布式锁是用于在分布式系统中控制对共享资源的访问的锁,可以跨越多个计算机或进程。分布式锁可以通过基于数据库、基于缓存(如 Redis)、基于 ZooKeeper 等方式来实现。

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

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

相关文章

面试题集中营—分布式共识算法

分布式共识算法目标 分布式主要就是为了解决单点故障。一开始只有一个服务节点提供服务,如下图所示。那么如果服务节点挂了,对不起等着吧。 为了服务的高可用性,我们一般都会多引入几个副节点当备份,当服务节点挂了,就…

【Java框架】Spring框架(四)——Spring中的Bean的创建与生命周期

目录 SpringBean的创建步骤后置处理器(PostProcessor)BeanFactoryPostProcessorBeanPostProcessorInstantiationAwareBeanPostProcessorpostProcessBeforeInstantiationpostProcessAfterInstantiationpostProcessProperties SmartInstantiationAwareBeanPostProcessordetermine…

如何采集opc服务器数据上传云端

为了进一步提高生产效率,生产制造的不断朝着智能化发展和升级,传统的自动化生产系统已经不能满足需求。传统的SCADA系统一般是用于现场的数据采集与控制,但是本地控制已经无法满足整个工厂系统智能化数字化的需求,智能化数字化是需…

呼叫系统的技术实现原理和运作流程,ai智能系统,呼叫中心外呼软交换部署

呼叫系统的技术实现原理和运作流程可以涉及多个组成部分,包括硬件设备、软件系统和通信协议。以下是一般情况下呼叫系统的技术实现原理和运作流程的概述: 硬件设备: 服务器:用于承载呼叫系统的核心软件和数据库。电话交换机&#…

《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)

1.简介 前面宏哥一连几篇介绍如何通过开源jar包Log4j.jar、log4j2.jar和logback实现日志文件输出,Log4j和logback确实很强大,能生成三种日志文件,一种是保存到磁盘的日志文件,一种是控制台输出的日志,还有一种是HTML格…

Docker 镜像仓库常见命令

Docker Registry (镜像仓库) 常用命令 docker login 功能:登录到一个 Docker 镜像仓库,如果没有指定镜像仓库的地址,默认就是官方的 Docker Hub 仓库。 语法: docker login [options] [server]选项: -u:登…

字母加密(C语言)

一、题目; 为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。例如,可以按以下规律将电文变成密码:将字母A变成字母E,a变成e,即变成其后的第4个字母,W…

[源码分享]基于Unity的Live2D虚拟人物——结合了GPT、Azure、情绪识别和口型同步,也可以集合苹果Vision Pro做成3D的形象

# 技术文档 ## 1 项目简介 ### 项目目录 ``` Assets ├─ Animator // 动画 ├─ Code // 代码 │ ├─ AI // AI 模块 │ │ ├─ LM // 语言模型模块 │…

基于Springboot+Vue的Java项目-网上购物商城系统开发实战(附演示视频+源码+LW)

大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &am…

数仓建模—数据仓库初识

数仓建模—数据仓库初识 数据仓库之父Bill Inmon在1991年出版的"Building the Data Warehouse"一书中所提出的定义被广泛接受 数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integ…

hv第一坑:定时器

错误代码 重试策略:一次延迟1s,最长30s直至事件成功。 int try_count 0;//do something if(not success)m_loop->setTimerInLoop((try_count > 30 ? 30: try_count) *1000 , cb, INFINITE, 0x100);表现现象 cpu 爆了内存爆了 总结原因 hv内部代码bug&…

C++异步回调示例:多线程执行任务,主线程通过回调监测任务状态

1、回调函数 回调函数定义:把函数的指针或者地址作为参数传递给另一个参数,当这个指针被用来调用其所指向的函数时,那么这就是一个回调的过程,这个被回调的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而…

Ubuntu20.04 ISAAC SIM仿真下载使用流程(4.16笔记补充)

机器:华硕天选X2024 显卡:4060Ti ubuntu20.04 安装显卡驱动版本:525.85.05 参考: What Is Isaac Sim? — Omniverse IsaacSim latest documentationIsaac sim Cache 2023.2.3 did not work_isaac cache stopped-CSDN博客 Is…

相机1:如何系相机肩带

开始解锁新领域,多看几个相关视频,大概也就可以掌握一两种系相机肩带的方法,本质就是新知识的学习过程,不可能等着或者期待出来一个完整的教程,一步一步自己去探索,自己去查资料。 目录 总述 第一步&#…

chrome 浏览器 f12 如何查看 websocket 消息?

1. 打开目标页面 2. f12--》网络--》WS,然后刷新页面( 如果不刷页面,就会看不到 websocket 请求,因为 websocket 是长连接,页面加载后只发出一次连接请求,不像 http 接口,不用刷新页面,待会儿也…

STM32F103 hal库 移植 freeRTos+LVGL

先配置freeRTOS 配置时钟 选用外部晶振 这里选用其他定时器,至于为什么我也不是很懂,好像说是跟稳定 配置FREERTOS 其他配置看着办 移植LVGL 先去gitee下载源码 选择一个版本 开始移植 1、添加lvgl源码到工程文件中 把lvgl-8.0.2\src文件夹直接复制…

SpringBoot(一)【入门】

前言 1、SpringBoot 快速入门 1.1、SpringBoot 简介 SpringBoot 是用来简化 Spring 应用的初始搭建以及开发过程 首先我们回顾一下 SpringMVC 项目的开发过程: 导入依赖(javax.servlet-api 和 spring-webmvc)Servlet 容器配置类&#xff…

227基于matlab的作业调度问题

基于matlab的作业调度问题。采用遗传算法,解决作业调度问题。一共三个作业,每个作业有不同的时间长度和紧急程度,超过时间会有惩罚措施。通过遗传算法计算出最好的作业安排,使得惩罚最小,获益最大。最终结果通过GUI用甘…

Maven 项目 JDK 8、JDK 17 多版本 Java 编译依赖最佳实践

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…

ubuntu下交叉编译ffmpeg到目标架构为aarch架构的系统

Ubuntu下FFmpeg的aarch64-linux-gnu架构交叉编译教程 一、前言 有时候真的很想报警的,嵌入式算法部署花了好多时间了,RKNN 1808真是问题不少;甲方那边也是老是提新要求,真是受不了。 由于做目标检测,在C代码中有对视…