原生redis实现分布式锁:
SETNX key value
setnx lock:001 123456
SET key value [EX seconds] [PX milliseconds] [NX|XX]
// EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
// PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
// NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
// XX :只在键已经存在时,才对键进行设置操作。
set lock:001 123456 ex 30 nx
// (SETNX命令与EXPIRE命令的二合一指令,确保加锁与设置超时时间是原子性的)
Redisson分布式锁
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* redis锁工具类
*
* @author xuyj
* @date 2021年09月28日 14:00
*/
@Component
public class RedisLock {
@Autowired
private RedissonClient redissonClient;
/**
* 获取锁
*
* @param lockKey 锁实例key
* @return 锁信息
*/
public RLock getRLock(String lockKey) {
return redissonClient.getLock(lockKey);
}
/**
* 加锁
*
* 这个分布式锁超时时间默认是30秒(可以通过Config.lockWatchdogTimeout来修改)。
* 加锁成功后,就会启动一个watchdog
* watchdog是一个后台线程,会每隔10秒检查一下客户端1是否还持有锁key;
* 如果是,就延长锁key的生存时间,延长操作就是再次把锁key的超时时间设置成30s。
*
* @param lockKey 锁实例key
* @return 锁信息
*/
public RLock lock(String lockKey) {
RLock lock = getRLock(lockKey);
lock.lock();
return lock;
}
/**
* 加锁
*
* @param lockKey 锁实例key
* @param leaseTime 上锁后自动释放锁时间
* @return true=成功;false=失败
*/
public Boolean tryLock(String lockKey, long leaseTime) {
return tryLock(lockKey, 0, leaseTime, TimeUnit.SECONDS);
}
/**
* 加锁
*
* @param lockKey 锁实例key
* @param leaseTime 上锁后自动释放锁时间
* @param unit 时间颗粒度
* @return true=加锁成功;false=加锁失败
*/
public Boolean tryLock(String lockKey, long leaseTime, TimeUnit unit) {
return tryLock(lockKey, 0, leaseTime, unit);
}
/**
* 加锁
*
* @param lockKey 锁实例key
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放锁时间
* @param unit 时间颗粒度
* @return true=加锁成功;false=加锁失败
*/
public Boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
RLock rLock = getRLock(lockKey);
boolean tryLock = false;
try {
tryLock = rLock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
return tryLock;
}
/**
* 释放锁
*
* @param lockKey 锁实例key
*/
public void unlock(String lockKey) {
RLock lock = getRLock(lockKey);
lock.unlock();
}
/**
* 释放锁
*
* @param lock 锁信息
*/
public void unlock(RLock lock) {
lock.unlock();
}
}