读写锁可以有效解决缓存一致性的问题。在读多写少的场景下,使用读写锁可以提高并发访问的效率,并保证缓存的一致性。具体实现方案如下:
@Component
public class RedisCache {
private static final String CACHE_PREFIX = "my-cache:";
private final RedisTemplate<String, Object> redisTemplate;
private final ReadWriteLock readWriteLock;
public RedisCache(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
this.readWriteLock = new ReentrantReadWriteLock();
}
public Object get(String key) {
readWriteLock.readLock().lock();
try {
return redisTemplate.opsForValue().get(CACHE_PREFIX + key);
} finally {
readWriteLock.readLock().unlock();
}
}
public void set(String key, Object value) {
readWriteLock.writeLock().lock();
try {
redisTemplate.opsForValue().set(CACHE_PREFIX + key, value);
} finally {
readWriteLock.writeLock().unlock();
}
}
public void delete(String key) {
readWriteLock.writeLock().lock();
try {
redisTemplate.delete(CACHE_PREFIX + key);
} finally {
readWriteLock.writeLock().unlock();
}
}
}
@Service
public class UserService {
private final RedisCache redisCache;
public UserService(RedisCache redisCache) {
this.redisCache = redisCache;
}
public User getUserById(Long userId) {
String key = "user:" + userId;
User user = (User) redisCache.get(key);
if (user == null) {
// 从数据库中查询用户信息
user = userDao.getUserById(userId);
// 将用户信息写入缓存
redisCache.set(key, user);
}
return user;
}
public void updateUser(User user) {
String key = "user:" + user.getId();
// 先删除缓存中的用户信息
redisCache.delete(key);
// 更新数据库中的用户信息
userDao.updateUser(user);
}
}
在以上示例中,我们使用了读写锁来保证缓存的一致性。在读取缓存数据时,使用读锁进行加锁,以实现并发读取。在写入缓存数据时,使用写锁进行加锁,以保证写入操作的原子性。
需要注意的是,读写锁只能在单个应用程序中保证缓存的一致性。如果有多个应用程序共享同一个缓存,需要使用分布式锁来保证缓存的一致性。
同时,在高并发场景下,使用读写锁会带来一定的性能开销。因此,需要根据实际情况来评估是否使用读写锁。