请谈谈ReadWriteLock和StampedLock
ReadWriteLock包括两种子锁:
1. ReadWriteLock ReadWriteLock 可以实现多个读锁同时进行,但是读与写和写于写互斥,只能有一个写锁线程在进行。
2. StampedLock StampedLock是Jdk在1.8提供的一种读写锁,相比较ReentrantReadWriteLock性能更好,因为ReentrantReadWriteLock在读写之间是互斥的,使用的是一种悲观策略,在读线程特别多的情况下,会造成写线程处于饥饿状态,虽然可以在初始化的时候设置为true指定为公平,但是吞吐量又下去了,而StampedLock是提供了一种乐观策略,更好的实现读写分离,并且吞吐量不会下降。
StampedLock包括三种锁:
1. 写锁writeLock:
writeLock是一个独占锁写锁,当一个线程获得该锁后,其他请求读锁或者写锁的线程阻塞, 获取成功后,会返回一个stamp(凭据)变量来表示该锁的版本,在释放锁时调用unlockWrite方法传递stamp参数。提供了非阻塞式获取锁tryWriteLock。
2. 悲观读锁readLock:
readLock是一个共享读锁,在没有线程获取写锁情况下,多个线程可以获取该锁。如果有写锁获取,那么其他线程请求读锁会被阻塞。悲观读锁会认为其他线程可能要对自己操作的数据进行修改,所以需要先对数据进行加锁,这是在读少写多的情况下考虑的。请求该锁成功后会返回一个stamp值,在释放锁时调用unlockRead方法传递stamp参数。提供了非阻塞式获取锁方法tryWriteLock。
3. 乐观读锁tryOptimisticRead:
tryOptimisticRead相对比悲观读锁,在操作数据前并没有通过CAS设置锁的状态,如果没有线程获取写锁,则返回一个非0的stamp变量,获取该stamp后在操作数据前还需要调用validate方法来判断期间是否有线程获取了写锁,如果是返回值为0则有线程获取写锁,如果不是0则可以使用stamp变量的锁来操作数据。
由于tryOptimisticRead并没有修改锁状态,所以不需要释放锁。
这是读多写少的情况下考虑的,不涉及CAS操作,所以效率较高,在保证数据一致性上需要复制一份要操作的变量到方法栈中,并且在操作数据时可能其他写线程已经修改了数据,而我们操作的是方法栈里面的数据,也就是一个快照,所以最多返回的不是最新的数据,但是一致性得到了保证。
相关推荐HOT
如何快速入门怎样学习java
要快速入门学习Java,你可以按照以下步骤进行:设置开发环境:首先,在你的计算机上安装Java开发工具包(JavaDevelopmentKit,JDK)。你可以从Ora...详情>>
2023-06-05 16:19:00SpringBoot整合JDBCTemplat
Spring Boot 是一个快速构建基于 Spring 框架的应用程序的工具,而 JdbcTemplate 是 Spring 框架中用于执行 SQL 语句的类。下面是 Spring Boot ...详情>>
2023-03-20 19:29:44举例说明什么情况下会更倾向于使用抽象类而不是接口?
接口和抽象类都遵循”面向接口而不是实现编码”设计原则,它可以增加代码的灵活性,可以适应不断变化的需求。下面有几个点可以帮助你回答这个问...详情>>
2022-11-07 14:34:20实例化创建对象有哪几种方式
1. new2. clone()3. 通过反射机制创建4. 序列化反序列化。反射示意代码:// Class.forName方法获取类,在调用类的newinstance()方法 Class cls ...详情>>
2022-11-07 14:33:23热门推荐
依赖注入实现原理?
沸如何快速入门怎样学习java
热SpringBoot整合JDBCTemplat
热一个bug的解决过程,让你明白阅读源码的重要性
新Redis的持久化机制有哪几种
高频面试题 - RabbitMQ如何防止重复消费问题
HashMap与ConcurrentHashMap的区别
线程和进程区别
JVM 是如何处理异常的?
如何实现跨域?说一下JSONP实现原理?
企业真实面试:父子类之间到底是怎么实例化的?
什么是 Spring Boot?Spring Boot 有哪些优点?
你了解过哪些同步器?请分别介绍下
新手java编程什么软件好