阅读量:2
在Spring中实现Redis分布式锁可以使用RedisTemplate来操作Redis进行加锁和解锁。
首先,我们需要定义一个分布式锁的实体类,包含锁的名称和锁的过期时间:
public class RedisLock { private String name; // 锁名称 private long expireTime; // 锁的过期时间 // 构造方法和Getter/Setter省略 }
接下来,我们可以创建一个工具类来实现加锁和解锁的逻辑:
@Component public class RedisLockUtil { private static final String LOCK_PREFIX = "redis_lock_"; // 锁的前缀 private static final long DEFAULT_EXPIRE_TIME = 30000L; // 默认锁的过期时间 @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 加锁 * @param lockName 锁的名称 * @return 加锁成功返回true,否则返回false */ public boolean lock(String lockName) { String key = LOCK_PREFIX + lockName; RedisLock redisLock = new RedisLock(key, DEFAULT_EXPIRE_TIME); ValueOperations<String, Object> operations = redisTemplate.opsForValue(); Boolean absent = operations.setIfAbsent(key, redisLock); if (absent != null && absent) { return true; // 加锁成功 } // 判断锁是否过期 RedisLock currentLock = (RedisLock) operations.get(key); if (currentLock != null && currentLock.getExpireTime() < System.currentTimeMillis()) { RedisLock newLock = new RedisLock(key, DEFAULT_EXPIRE_TIME); RedisLock oldLock = (RedisLock) operations.getAndSet(key, newLock); if (oldLock != null && oldLock.getExpireTime() < System.currentTimeMillis()) { return true; // 加锁成功 } } return false; // 加锁失败 } /** * 解锁 * @param lockName 锁的名称 */ public void unlock(String lockName) { String key = LOCK_PREFIX + lockName; redisTemplate.delete(key); } }
使用示例:
@Service public class MyService { @Autowired private RedisLockUtil redisLockUtil; public void doSomething() { // 加锁 boolean locked = redisLockUtil.lock("myLock"); if (locked) { try { // 执行业务逻辑 } finally { // 解锁 redisLockUtil.unlock("myLock"); } } else { // 加锁失败,处理业务逻辑 } } }
在以上示例中,RedisLockUtil
定义了一个lock
方法来进行加锁操作,使用setIfAbsent
方法尝试将锁的值存入Redis,如果返回值为true表示加锁成功。如果加锁失败,则判断当前锁是否已经过期,如果过期则使用getAndSet
方法尝试更新锁的值,并判断返回的旧值是否已经过期,如果过期表示加锁成功。最后,unlock
方法通过删除锁的键来释放锁。