当前位置: 首页 > 后端技术 > Java

Java并发编程-StampedLock高性能读写锁

时间:2023-04-01 22:10:49 Java

[TOC]1.读写锁我在上篇文章《java并发编程》中介绍了《ReentrantLock读写锁》,ReentrantReadWriteLock可以保证最多一个线程同时写time数据,或者多个线程可以同时读取数据,但是读取和写入不能同时进行。比如你正在做的是日志记录,一个线程在做写操作,但是在写日志的时候,你可能需要把日志集中传输到集中管理的日志服务,但是此时读取线程是读不到数据的(因为无法获取读锁)。面对这种需求,ReentrantReadWriteLock显然不是我们的解决方案。我们希望最多一个线程在写(加写锁),但允许多个线程同时读(加读锁)。解决方案是StampedLock。2.悲观读锁StampedLock也可以实现写锁和读锁的功能。Stamped在英文中有印章的意思。对于StampedLock,大家可以这么理解,如果用印章锁,就一定要用印章解锁。公共类TestStampedLock{Mapmap=newHashMap<>();//锁定对象privateStampedLocklock=newStampedLock();//写操作函数publicvoidput(Stringkey,Stringvalue){longstamp=lock.writeLock();//添加写锁try{map.put(key,value);//写操作}finally{lock.unlockWrite(stamp);//释放写锁}}publicStringget(Stringkey){longstamp=lock.readLock();//添加读锁try{returnmap.get(key);//读操作}finally{lock.unlockRead(stamp);//释放读锁}}}上面的读锁readLock在StampedLock模式中称为悲观读锁。之所以称为悲观读锁,对应的是StampedLock支持的另一种模式“乐观读”。写锁和悲观读锁的语义与ReadWriteLock基本相同。允许多个线程同时获取悲观读锁,但只允许一个线程获取写锁。写锁和悲观读锁是互斥的。训斥。在多线程环境下,写操作不能同时读。所以到这里为止,StampedLock与ReadWriteLock并没有太大区别。3.乐观读需要注意的是,我这里写的是乐观读,不是乐观读锁,因为乐观读不加锁。通过tryOptimisticRead()函数获取戳记。在这里,tryOptimisticRead()是乐观阅读。乐观读没有锁,所以读取数据的性能会更高。即:虽然写操作线程已经有了锁,但读操作线程仍然可以继续执行。如果你的读写操作对时间点数据一致性要求比较强,即读操作在同一个时间点读取的数据必须和写操作在该时间点保持数据一致性。然后,您需要执行验证检查。戳记此时可以理解为版本号。如果写操作版本为2,读操作版本为1,说明你读取的数据不是最新的。需要读取最新版本的数据(版本号为2),所以需要升级为悲观读锁,代码如下:publicStringreadWithOptimisticLock(Stringkey){longstamp=lock.tryOptimisticRead();//乐观读取Stringvalue=map.get(key);//读取数据if(!lock.validate(stamp)){//检查数据是否为最新版本stamp=lock.readLock();//如果不是,升级为悲观读Locktry{returnmap.get(key);}最后{lock.unlock(stamp);}}returnvalue;}欢迎关注我的博客,更多精品知识汇集转文):字母哥博客-zimug.com如果觉得对您有帮助,请点赞转发!您的支持是我创作不竭的动力!.另外,作者近期输出了以下优质内容,期待大家的关注。《kafka修炼之道》《手摸手教你学Spring Boot2.0》《Spring Security-JWT-OAuth2一本通》《实战前后端分离RBAC权限管理系统》《实战SpringCloud微服务从青铜到王者》

猜你喜欢