网站首页 > java教程 正文
锁优化-读写锁
public Product getProductByReadWriteLock(Long productId) {
String redisId = SystemConstants.REDIS_KEY_PREFIX + productId;
// 1. 先查redis缓存
Product product = getProductFromRedis(redisId);
if (product != null) {
return product;
}
// 加写锁
ReadWriteLock readWriteLock = redisson.getReadWriteLock(SystemConstants.LOCK_HOT_UPDATE_PREFIX + productId);
Lock writeLock = readWriteLock.writeLock();
writeLock.lock();
// 2. DCL再查redis,因为只要有一次查询数据库操作,redis就已经有缓存数据了
Product productMysql;
try {
product = getProductFromRedis(redisId);
if (product != null) {
return product;
}
// 3. 加读锁 读数据库
ReadWriteLock readWriteLock2 = redisson.getReadWriteLock(SystemConstants.LOCK_HOT_UPDATE_PREFIX + productId);
Lock readLock = readWriteLock2.readLock();
readLock.lock();
productMysql = getProductFromMysql(productId);
readLock.unlock();
} finally {
writeLock.unlock();
}
return productMysql;
}
这是一段 Java 代码,主函数为 "getProductByReadWriteLock",该函数接收一个名为 productId 的参数,用于在 Redis 数据库和 MySQL 数据库中获取 Product 对象。
当函数被调用时,首先会根据 productId 生成一个唯一的 Redis 键值,然后尝试在 Redis 缓存中获取 Product 对象。如果 Redis 缓存中存在 Product 对象,那么函数会直接返回这个对象。
如果在 Redis 缓存中找不到该 Product 对象,那么函数会使用 Redisson 库获取另一个唯一的 Redis 键值对应的写锁。写锁在这里用于保护即将进行的可能会改变数据状态的操作,确保这些操作是原子性执行的。
获取到写锁后,函数将再次尝试从 Redis 缓存中获取 Product 对象。这是因为在获取写锁的过程中,可能已经有其他的线程获取到该 Product 对象并已经更新到了 Redis 缓存中。如果此时能在 Redis 缓存中找到 Product 对象,那么函数将直直接返回这个对象,并释放已经获取的写锁。
如果在 Redis 缓存中仍然找不到 Product 对象,那么函数将使用 Redisson 库获取相同的 Redis 键值对应的读锁。读锁在这里主要用于保护即将从 MySQL 数据库中读取的 Product 数据,确保在读取数据的过程中,MySQL 数据库中的这个 Product 数据不会被其他函数写入或修改。
当获取到读锁后,函数将从 MySQL 数据库中根据 productId 读取 Product 对象,然后释放读锁,并返回从 MySQL 数据库中获取的 Product 对象。
不论在执行过程中遇到怎样的情况,函数在最后都会确保释放已经获取的锁,防止发生死锁的情况。
通过使用 Redisson 库实现的读写锁,可以优化数据在高并发环境下的读写操作,提高系统的读写效率,从而提高系统的整体性能。
优点:
- 并发性:使用读写锁,当读操作的数量大于写操作时,可以大大提高系统的并发能力。
- 缓存一致性:通过在读取数据库之前先获取写锁再进行二次Redis检查,可以保证缓存和数据库之间的数据一致性。
- 避免死锁:代码中正确地在finally块中释放了锁,能有效地防止因异常情况而导致的死锁。
缺点:
- 对锁管理的依赖性较高:如果Redis缓存或Redisson锁服务无法正常工作,会直接影响到系统的正常运行。
- 锁粒度较大: 在这个例子中,读写锁的粒度是以整个产品对象为单位,在高并发的场景下,如果对同一productId的请求非常频繁,可能会导致其他请求需要等待释放锁而造成性能瓶颈。
- 可能会引发其他问题:使用读写锁可能会引发其他问题,比如惊群现象,在写锁释放后,大量读请求同时唤醒来争抢锁,导致过大的CPU使用率。
猜你喜欢
- 2025-05-24 腾讯面试:什么锁比读写锁性能更高?
- 2025-05-24 Linux系统编程—读写锁rwlock
- 2025-05-24 谈谈在Bitcask中用读写锁实现并发控制的性能表现
- 2025-05-24 Java并发工具:ReentrantReadWriteLock
- 2025-05-24 3个真实案例,彻底吃透读写锁ReentrantReadWriteLock
- 2025-05-24 Java多线程编程中的锁机制剖析
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)