有没有比读写锁更快的锁

这篇具有很好参考价值的文章主要介绍了有没有比读写锁更快的锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在之前的文章中,我们介绍了读写锁,学习完之后你应该已经知道了读写锁允许多个线程同时访问共享变量,适用于读多写少的场景。那么在读多写少的场景中还有没有更快的技术方案呢?还真有,在Java1.8这个版本里提供了一种叫StampedLock的锁,它的性能就比读写锁还要好。
下面我们介就来介绍一下StampedLock的使用方法、内部工作原理以及在使用过程中需要注意的事项。

StampedLock支持的三种模式

我们先来看看StampedLock在使用什么,和上篇文章中的ReadWriteLock所有哪些区别。
ReadWriteLock支持两种模式,一种是读锁,一种是写锁,而StampedLock支持三种模式,分别是写锁、悲观锁锁、乐观读,其中写锁、悲观读锁的语义和ReadWriteLock的写锁、读锁的语义非常类似。允许多个线程同时获取悲观读锁,但是只允许一个线程获取写锁,写锁和悲观读锁都是互斥的,然而不同的是里面的写锁和悲观读锁加锁成功之后,都会返回一个stamp。然后解锁的时候需要传入这个stamp。相关的实例代码如下。

final StampedLock sl = new StampedLock();

//获取/释放悲观读锁示意代码
long stamp = sl.reaLock();
try{
	//省略业务代码
} finally {
	sl.unlockRead(stamp);
}

//获取/释放写锁示意代码
long stamp = sl.writeLock();
try{
	//省略相关业务代码
} finally {
	sl.unlockWrite(stamp);
}

StampedLock 的性能之所以比ReadWriteLock还要好,关键是StampedLock支持乐观读的方式。ReadWriteLock支持多个线程同时读,但是当多个线程同时读的时候,所有的写操作也会被阻塞。而StampedLock提供的乐观读是允许一个线程获取写锁的,也就是说不是所有写操作都被阻塞的。
注意,这里我们用的是"乐观读"这个词,而不是乐观读锁,是要提醒你,乐观读操作是无锁的,所以相比较ReadWriteLock的读锁,乐观读的性能更好一点。文中下面这段代码是出自于Java SDK官方示例,并略作修改。在distanceFromRrigin()这个方法中,首先通过调用tryOptimisticRead获得了一个stamp。这里的tryOptimisticRead就是我们前面提到的乐观读。之后将共享变量X和Y读入方法的局部变量中。不过需要注意的是,由于tryOptimisticRead是无锁的,所以共享变量X和Y读入方法局部变量时,X和Y有可能被其他线程修改了,因此最后读完之后还需要再次验证一下是否存在写操作,这个操作是通过调用validate (stamp)来实现的。

class Point {
	private int x,y;
	final StampedLock sl = new StampedLock();
	//计算到原点的距离
	int distanceFromOrigin(){
		//乐观读
		long stamp = sl.tryOptimisticRead();
		//读入局部变量
		//读的过程中数据可能被修改
		int curX = x,curY = y;
		//判断执行读操作期间,是否存在写操作
		//如果存在,返回false
		if(!sl.validate(stamp)){
			//升级为悲观锁
			stamp = sl.readLock();
			try{
				curX = x;
				curY = y;
			} finally {
				sl.unLockRead(stamp);
			}
		}
		return Math.sqrt(curX * curX + curY * curY);
	}
}

在上面这个代码示例中,如果执行乐观读操作期间存在写操作,会把乐观读升级为悲观读锁。这个做法挺合理的,否则你就需要在一个循环里反复执行乐观读,直到执行乐观读操作期间没有写操作,只有这样才能保证X和Y的正确性和一致性。而循环读会浪费大量的CPU。升级为悲观读锁代码简练且不易出错,建议你在具体实践的时候也采用这样的方法。

进一步理解乐观读

如果你曾经用过数据库的乐观锁,你可能会发现StampLock的乐观读和数据库的乐观读锁有异曲同工之妙。的确是这样的,就我个人而言,我是先接触数据库的乐观锁,然后再接触的StampLock,我就觉得我前期数据库里的乐观锁的学习,对于后面的理解StampLock的乐观读有很大的帮助,所以这里有必要再介绍一下数据库里的乐观锁。
还记得我第一次使用数据库乐观锁的场景是这样的,在ERP的生产模块里,会有多个人通过ERP系统提供的UI同时修改同一条生产订单,那如何保证生产订单数据是并发安全的呢?我采用的方案就是乐观锁。
乐观锁的实现很简单,在生产订单的表product_doc里面增加一个数字型的版本号字段version,每次更新product_doc这个表的时候,都将version字段加1。生产订单的UI在展示的时候需要查询数据库。此时将这个version字段和其他业务字段一起返回给生产订单UI。假设用户查询的生产订单的ID=777,那么SQL语句类似于下面这样。

select id,....,version
from product_doc
where id = 777

用户在生产订单UI执行保存操作时候,后台利用下面的SQL语句更新生产订单,此时我们假设该条生产订单的version等于9。

update product_doc
set version=version+1
where id=777 and versoin=9

如果这条语SQL语句成执行成功,并且返回的条数等于1,那么说明从生产订单UI执行查询操作到执行保存操作期间没有其他人修改过这条数据。因为如果这期间其他人修改过这条数据,那么版本号一定会大于9。
你会发现数据库里的乐观锁查询的时候需要把version字段查出来,更新的时候要利用version字段做校验,这个version字段就类似于StampLock里面的stamp,这样对比着看,你相信你会更容易理解StampLock里面乐观读的用法。

StampLock使用注意事项

对于读多写少的场景StampLock性能很好,简单的应用场景基本上可以替代ReadWriteLock,但是StampLock的功能仅仅是ReadWriteLock的子集,在使用的时候还是有几个需地方需要注意一下。
StampLock在命名上并没有增加Reentrant,想必你已经猜到了,StampLock应该是不可重入的,事实上的确是这样的,StampLock不支持重入,这个是在使用中必须要注意的。
另外StampLock的悲观读锁、写锁都不支持条件变量,这个你也需要注意。
还有一点需要特别注意,那就是如果线程阻塞在StampLock的readLock()上时,此时调用该阻塞线程的interrupt()方法会导致CPU飙升。
所以使用StampLock一定不要调用中断操作,如果需要支持中断功能,一定使用可中断的悲观读锁readLockInterruptibly()和写锁writeLockInterruptibly(),这个规则一定要记清楚。

总结

StampLock的使用看上去有点复杂,但是如果你能理解乐观所背后的原理,使用起来还是比较流畅的。文章来源地址https://www.toymoban.com/news/detail-656864.html

到了这里,关于有没有比读写锁更快的锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • @Conditional+@Configuration有没有搞头?

    在了解 @Conditional 之前先花 10 秒钟复习一下 @Configuration 这个注解。 @Configuration 是干什么? 是配合 @Bean 注解来配置 Spring 容器的 bean 的。 那它为什么会出现呢? 因为配置 bean 的另一种方式是 xml ,狗都不用。 那给个示例看看呗? 简单。 下面进入主题: @Conditional 是什么东西

    2024年02月03日
    浏览(56)
  • 怎么看自己有没有安装tensorflow

    如果您想检查计算机上是否已安装 TensorFlow,您可以尝试执行以下步骤: 打开命令行终端。 在命令行中输入 \\\"python\\\",然后按回车键,打开 Python 解释器。 在 Python 解释器中,输入 \\\"import tensorflow\\\",然后按回车键。 如果 TensorFlow 已安装,您将不会看到任何错误消息。相反,您将

    2024年02月16日
    浏览(58)
  • 有没有免费版的配音软件?

    先不要着急去买付费的配音软件。 (我就被忽悠过,买了付费配音软件后,实际没用几次) 当你明确的知道,剪映配音的不足时,再考虑选付费的配音软件。 img src=\\\"https://picx.zhimg.com/50/v2-95aba0d9f80af68ad0cb25c5afbee450_720w.jpg?source=1940ef5c\\\" data-caption=\\\"\\\" data-size=\\\"small\\\" data-rawwidth=\\\"821\\\"

    2024年02月07日
    浏览(52)
  • 有没有高效便捷的视频下载工具?

    做影视剪辑或者后期工作的小伙伴们,经常需要扒一些视频作为素材,今天给大家分享四个高效便捷的视频下载工具,总有一个你满意的! 一、 Downni 一个超级视频下载工具,支持全网1000+平台视频的解析,页面清爽整洁,功能一目了然,支持不同分辨率的格式下载,还可以

    2024年02月08日
    浏览(52)
  • 使用键盘测试图解(测试键盘有没有失灵)

    键盘是很容易坏的电脑外置设备,也是必不可少的电脑用品,经常使用电脑 特别是程序猿(媛)更是每天都在使用 键盘很容易出现问题,键盘失灵后有的字或者数字打不出来特别烦人。这里给您提供一个方法,测试您键盘按键的好坏在线测试工具,每按一下键盘上按键,就

    2024年02月12日
    浏览(50)
  • 怎么知道网站服务器有没有被攻击?

    ​ 一个网站服务器遭到攻击可能会给企业带来巨大的金融损失,因此,企业需要及时发现服务器是否被攻击。但是,企业如何知道自己的服务器是否被攻击呢?下面,我们来看一些服务器被攻击的警告信号。   1.网络延迟增加 在网络攻击中,攻击者的行为会导致服务器和网络

    2024年02月02日
    浏览(191)
  • 软考中级到底有没有用?价值高吗?

    软考中级证书是国家计算机技术与软件专业职业资格认证的一种,是IT行业中较为实用的证书之一。它对于个人职业发展和企业提升都有着重要的意义。本文将从个人和企业两个角度来探讨软考中级证书的价值。 1.提高职业技能水平 软考中级证书是一种专业水平的认证,证明

    2023年04月15日
    浏览(48)
  • ubuntu 系统 怎么判断系统有没有GPU

    在 Ubuntu 系统中,您可以通过几种方式来检查系统是否包含显卡,以及显卡的详细信息。以下是一些常用的方法: lspci 命令 : 打开终端。 输入 lspci | grep VGA 命令。 这将显示系统中所有的 VGA 兼容设备,通常是您的显卡。 lshw 命令 : 在终端中输入 sudo lshw -C display 。 这将提供

    2024年04月15日
    浏览(49)
  • Level 2 十档行情到底有没有用?

    这两年股市操作难度很大,很多券商和三方平台都推出了Level 2 十档行情的工具来辅助大家炒股,像有些券商会给20w以上的客户 免费送Level 2 十档行情 。像同花顺这种平台,Level 2 行情一年的费用就是 298元 ,所以如果可以 免费 拿到这个辅助工具,还是很划算的! 但是你真的

    2024年02月09日
    浏览(44)
  • 有没有可以代替风铃系统的专业问卷工具?

    风铃系统问卷是一种流行的调查和数据分析工具,已广泛应用于学术研究、市场营销和社会科学。然而,有几种替代产品提供了与风铃系统类似的特性和功能,可以被企业用来进行调查和分析数据。在这篇文章中,我们将介绍 风铃系统的十大替代产品 以及它们的特点。 1、

    2024年02月09日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包