Java中锁的分类

引言

在多线程并发编程场景中,锁作为一种至关重要的同步工具,承担着协调多个线程对共享资源访问秩序的任务。其核心作用在于确保在特定时间段内,仅有一个线程能够对资源进行访问或修改操作,从而有效地保护数据的完整性和一致性。锁作为一种底层的安全构件,有力地防止了竞态条件和数据不一致性的问题,尤其在涉及多线程或多进程共享数据的复杂场景中显得尤为关键。

而了解锁的分类,能帮助我们何种业务场景下使用选择哪种锁。

Java中锁分类.jpg

基于锁的获取与释放方式分类

计划于所得获取与释放方式进行分类,Java中的锁可以分为:显式锁和隐式锁。

隐式锁

Java中的隐式锁(也称为内置锁或自动锁)是通过使用synchronized关键字实现的一种线程同步机制。当一个线程进入被synchronized修饰的方法或代码块时,它会自动获得对象级别的锁,退出该方法或代码块时则会自动释放这把锁。

在Java中,隐式锁的实现机制主要包括以下两种类型:

  1. 互斥锁(Mutex): 虽然Java标准库并未直接暴露操作系统的互斥锁提供使用,但在Java虚拟机对synchronized关键字处理的底层实现中,当锁竞争激烈且必须升级为重量级锁时,会利用操作系统的互斥量机制来确保在同一时刻仅允许一个线程持有锁,从而实现严格的线程互斥控制。

  2. 内部锁(Intrinsic Lock)或监视器锁(Monitor Lock): Java语言为每个对象内建了一个监视器锁,这是一个更高级别的抽象。我们可以通过使用synchronized关键字即可便捷地管理和操作这些锁。当一个线程访问被synchronized修饰的方法或代码块时,会自动获取相应对象的监视器锁,并在执行完毕后自动释放,这一过程对用户透明,故被称为隐式锁。每个Java对象均与一个监视器锁关联,以此来协调对该对象状态访问的并发控制。

优点:

  1. 简洁易用:程序员无需手动管理锁的获取和释放过程,降低了编程复杂性。
  2. 安全性:隐式锁确保了线程安全,避免了竞态条件,因为一次只有一个线程能持有锁并执行同步代码块。
  3. 异常处理下的自动释放:即使在同步代码块中抛出异常,隐式锁也会在异常退出时被释放,防止死锁。

缺点:

  1. 锁定粒度:隐式锁的粒度通常是对象级别,这意味着如果一个大型对象的不同部分实际上可以独立地被不同线程访问,但由于整个对象被锁定,可能导致不必要的阻塞和较低的并发性能。
  2. 不灵活:相对于显示锁(如java.util.concurrent.locks.Lock接口的实现类),隐式锁的功能较有限,无法提供更细粒度的控制,如尝试获取锁、定时等待、可中断的获取锁等高级特性。
  3. 锁竞争影响:在高并发环境下,若多个线程竞争同一把锁,可能会引发“锁争用”,导致性能下降,特别是在出现锁链和死锁的情况下。

适用场景: 隐式锁适用于相对简单的多线程同步需求,尤其是在只需要保护某个对象状态完整性,且无需过多关注锁策略灵活性的场合。对于要求更高并发性和更复杂锁管理逻辑的应用场景,显示锁通常是一个更好的选择。

显式锁

显式锁是由java.util.concurrent.locks.Lock接口及其诸多实现类提供的同步机制,相较于通过synchronized关键字实现的隐式锁机制,显式锁赋予开发者更为精细和灵活的控制能力,使其能够在多线程环境中精准掌控同步动作。显式锁的核心作用在于确保在任何时刻仅有一个线程能够访问关键代码段或共享数据,从而有效防止数据不一致性问题和竞态条件。

相较于隐式锁,显式锁提供了更为多样化的锁操作选项,包括但不限于支持线程在等待锁时可被中断、根据先后顺序分配锁资源的公平锁与非公平锁机制,以及能够设定锁获取等待时间的定时锁功能。这些特性共同增强了显式锁在面对复杂并发场景时的适应性和可调控性,使之成为解决高度定制化同步需求的理想工具。

日常开发中,常见的显式锁分类有如下几种:

  1. ReentrantLock:可重入锁,继承自Lock接口,支持可中断锁、公平锁和非公平锁的选择。可重入意味着同一个线程可以多次获取同一线程持有的锁。
  2. ReentrantReadWriteLock:读写锁,提供了两个锁,一个是读锁,允许多个线程同时读取;另一个是写锁,同一时间内只允许一个线程写入,写锁会排斥所有读锁和写锁。
  3. StampedLock:带版本戳的锁,提供了乐观读、悲观读写模式,适合于读多写少的场景,可以提升系统性能。

优点:

  1. 灵活控制:显式锁提供了多种获取和释放锁的方式,可以根据实际需求进行选择,比如中断等待锁的线程,设置超时获取锁等。
  2. 性能优化:在某些特定场景下,显式锁可以提供比隐式锁更好的性能表现,尤其是当需要避免死锁或优化读多写少的情况时。
  3. 公平性选择:显式锁允许创建公平锁,按照线程请求锁的顺序给予响应,保证所有线程在等待锁时有一定的公平性。

缺点:

  1. 使用复杂:相较于隐式锁,显式锁需要手动调用lock()unlock()方法,增加了编程复杂性,如果不正确地使用(如忘记释放锁或未捕获异常导致锁未释放),容易造成死锁或其他并发问题。
  2. 性能开销:在某些简单场景下,显式锁的额外API调用和锁状态管理可能带来额外的性能开销,尤其当公平锁启用时,由于需要维护线程队列和线程调度,可能会影响整体性能。
  3. 错误可能性:由于显式锁的操作更加细致,因此更容易出错,开发者需要具备较高的并发编程意识和技能才能妥善使用。

基于对资源的访问权限

按照线程对资源的访问权限来分类,可以将锁分为:独占锁(Exclusive Lock)和共享锁(Shared Lock)。

独占锁

独占锁(Exclusive Lock),又称排他锁或写锁,是一种同步机制,它确保在任一时刻,最多只有一个线程可以获得锁并对受保护的资源进行访问或修改。一旦线程获得了独占锁,其他所有试图获取同一锁的线程将被阻塞,直到拥有锁的线程释放锁为止。独占锁主要用于保护那些在并发环境下会被多个线程修改的共享资源,确保在修改期间不会有其他线程干扰,从而维护数据的一致性和完整性。

对于独占锁就像图书馆里的某本书,这本书只有唯一的一本。当一个读者想要借阅这本书时,他会去图书管理员那里登记并拿到一个“借书凭证”(相当于独占锁)。此时,这本书就被锁定了,其他读者无法借阅这本书,直至第一个读者归还书本并交回“借书凭证”。这就像是线程获得了独占锁,只有拥有锁的线程可以修改或操作资源(书本),其他线程必须等待锁的释放才能执行相应的操作。

而独占锁的实现方式,主要有如下两种:

  1. synchronized关键字:通过synchronized关键字实现的隐式锁,它是独占锁的一种常见形式,任何时刻只有一个线程可以进入被synchronized修饰的方法或代码块。
  2. ReentrantLock:可重入的独占锁,提供了更多的控制方式,包括可中断锁、公平锁和非公平锁等。

优点:

  1. 简单易用:对于synchronized关键字,语法简单直观,易于理解和使用。
  2. 线程安全:确保了对共享资源的独占访问,避免了并发环境下的数据竞争问题。
  3. 可重入性:像ReentrantLock这样的锁,支持同一个线程重复获取同一把锁,提高了线程间协作的便利性。

缺点:

  1. 粒度固定:对于synchronized,锁的粒度是固定的,无法动态调整,可能导致不必要的阻塞。
  2. 缺乏灵活性:隐式锁不能主动中断等待锁的线程,也无法设置超时等待。
  3. 性能瓶颈:在高度竞争的环境中,synchronized可能会造成上下文切换频繁,效率低下;而显式锁虽提供了更灵活的控制,但如果使用不当也可能导致额外的性能损失。

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

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

相关文章

Qt开发(2)——在已有VS项目中配置Qt

在之前的Qt开发学习中,基本都是在Qt Creator中创建一个Qt项目,或者即便是在VS中也是直接新建一个Qt项目。但很少有记录如何在已有的C项目中添加Qt,这就好比我有个项目已经开发完了,现在又说加个Qt界面的功能。这篇文章就是记录如何在已有项目…

Programming Abstractions in C阅读笔记:p338-p346

《Programming Abstractions in C》学习第80天,p338-p346,总计9页。 一、技术总结 栈的实现包括入栈、出栈、判断栈是否为满,判断栈是否为空等。作者结合RPN计算器来实现,稍显无聊。 /** File: rpncalc.c* ---------------* Th…

VMware和Xshell连接

1.开启虚拟机 2.使用管理员账户,点击未列出 3.输入用户名密码 4.点击编辑虚拟网络编辑器 5.记住自己的网关和IP地址 6.打开终端 7.输入命令,vim / etc / sysconfig / network -scripts / ifcfg-ens33 回车 8.修改图中两处按“ I ”键进入编辑 d…

号码采集协议讲解

仅供学习研究交流使用 需要的进去拿源码或者成品

k8s1.28.8版本安装prometheus并持久化数据

本文参考 [k8s安装prometheus并持久化数据_/prometheus-config-reloader:-CSDN博客](https://blog.csdn.net/vic_qxz/article/details/119598466)前置要求: 已经部署了NFS或者其他存储的K8s集群. 这里注意networkpolicies网络策略问题,可以后面删除这个策略&#x…

Mysql连接查询

目录 一、连接查询 1.1内连接 1.2 左连接 1.3 右连接 二、存储过程 2.1 简介 2.2 优点 2.3语法 2.4 创建与调用存储过程 ​编辑2.4.1 查看存储过程 2.5 存储过程的参数 2.6 删除存储过程 一、连接查询 MySQL 的连接查询,通常都是将来自两个或多个表的记录…

如何利用nginx在windows系统上搭建一个文件服务器

1:先下载windows版的nginx 官网 http://nginx.org/ 下载完后注意端口号(默认端口号为:80)是否被占用 启动nginx服务 地址为localhost的 如果出现 Welcome to nginx 就说明启动成功 2:然后进入conf文件里修改配置 …

Mysql数据库——高级SQL语句补充

目录 一、子查询——Subquery 1.环境准备 2.In——查询已知的值的数据记录 2.1子查询——Insert 2.2子查询——Update 2.3子查询——Delete 3.Not In——表示否定,不在子查询的结果集里 3.Exists——判断查询结果集是否为空 4.子查询——别名 二、视图—…

GPIO端口的BSRR的使用

BSRR 只写寄存器 既能控制管脚为高电平,也能控制管脚为低电平。对寄存器高 16bit 写1 对应管脚为低电平,对寄存器低16bit写1对应管脚为高电平。写 0 ,无动作 首先看GPIOC的定义 接着看这个类型的定义 可以看到BSRR为无符号的32位的整形 接下来看GPIO_Pi…

【旅游】泉州攻略v1.0.0

一、泉州古城 泉州市距离深圳大约520公里,从深圳北站出发,高铁大约3小时30分。 到达泉州西站后,往东南方向大约8公里,就可以到达主要的旅游景点泉州古城。 古城很适合使用一天玩耍,核心路线如下: 一路的景…

python安装与使用

1安装 1.0下载 从官网下载安装包欢迎来到 Python.orghttps://www.python.org/ 1.1安装 双击安装包 将 图中选项勾选 之后如图 在点击 等待安装,安装之后关闭(Close) 2实现第一个python程序 2.0打开python运行环境 安装之后在开始菜单…

8.HelloWorld小案例

文章目录 一、Java程序开发运行流程如何理解编译? 二、HelloWorld案例的编写1、新建文本文档文件,修改名称为HelloWorld.java。2、用记事本打开HelloWorld.java文件,输写程序内容。代码要跟我编写的完全保持一致。3、ctrl s 保存&#xff0c…

【Java程序设计】【C00389】基于(JavaWeb)Springboot的校园疫情防控系统(有论文)

基于(JavaWeb)Springboot的校园疫情防控系统(有论文) 项目简介项目获取开发环境项目技术运行截图 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过…

【C++】用哈希桶模拟实现unordered_set和unordered_map

目录 一、哈希介绍1.1 哈希概念1.2 哈希冲突解决1.2.1 闭散列1.2.2 开散列 二、哈希桶2.1 实现哈希桶2.1.1 构造节点和声明成员变量2.1.2 构造与析构2.1.3 仿函数2.1.4 查找2.1.5 插入2.1.6 删除 2.2 kv模型哈希桶源代码 三、改造哈希桶3.1 beginend3.2 迭代器3.2.1 前置 3.3 改…

【C语言】strcmp 的使⽤和模拟实现

前言 这篇文章将要带我们去实现模拟一个strcmp函数 首先我们要知道strcmp函数的定义 strcmp()定义和用法 我们先看一下strcmp在cplusplus网站中的定义 链接: link int strcmp ( const char * str1, const char * str2 );比较两个字符串将 C 字符串 str1 与 C 字符串 str2 …

pin脚的缺陷检测

忍不住 我才是最大的缺陷首先应该学好表达头脑风暴分割paddledetection小目标检测也不行缺陷检测1.缺陷标注修改代码为自己的数据集训练训练结果结果图片 结论再次出发 我才是最大的缺陷 真的,我真的被整无语了。测测测测,测个鬼。一天天的净整些没用的…

国内ip地址推荐,畅享网络新体验!

在数字化时代,IP地址不仅是网络连接的基石,也是互联网产业发展的重要标志。国内作为全球互联网市场的重要参与者,拥有众多IP地址资源。虎观代理小二旨在探索并推荐一些国内IP地址,分析它们的价值所在,并探讨如何更好地…

数据结构和算法:搜索

二分查找 二分查找(binary search) 是一种基于分治策略的高效搜索算法。它利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空为止。 给定一个长度为 𝑛 的数组 nums ,元素按从小到大…

PTA L2-036 网红点打卡攻略

一个旅游景点,如果被带火了的话,就被称为“网红点”。大家来网红点游玩,俗称“打卡”。在各个网红点打卡的快(省)乐(钱)方法称为“攻略”。你的任务就是从一大堆攻略中,找出那个能在…

精品凉拌菜系列热卤系列课程

这一系列课程涵盖精美凉拌菜和美味热卤菜的制作技巧。学员将学习如何选材、调味和烹饪,打造口感丰富、色香俱佳的菜肴。通过实践训练,掌握独特的烹饪技能,为家庭聚餐或职业厨艺提升增添亮点。 课程大小:6.6G 课程下载&#xff1…