1、依赖包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>1.5.2.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
2、redis 工具类
@Component
public class RedisStringUtil {
/**
* 注入Redis字符串模板
*/
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 设置值
*
* @param key 键
* @param value 值
*/
public void set(String key, String value) {
this.redisTemplate.opsForValue().set(key, value);
}
/**
* 当前的值 + 1
*
* @param key 键
* @return 返回操作之后的值
*/
public Long increment(String key) {
return this.redisTemplate.opsForValue().increment(key, 1);
}
/**
* 当前的值加 + value
*
* @param key 键
* @param value 值
* @return 返回操作之后的值
*/
public Long incrementBy(String key, long value) {
return this.redisTemplate.opsForValue().increment(key, value);
}
/**
* 当前的值 - 1
*
* @param key 键
* @return 返回操作之后的值
*/
public Long descend(String key) {
return this.redisTemplate.opsForValue().increment(key, -1);
}
/**
* 当前的值 - value
*
* @param key 键
* @return 返回操作之后的值
*/
public Long descendBy(String key, long value) {
return this.redisTemplate.opsForValue().increment(key, -Math.abs(value));
}
/**
* 设置值
*
* @param key 键
* @param value 值
* @param timeout 超时(秒)
*/
public void set(String key, String value, long timeout) {
this.redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
}
/**
* 设置值
*
* @param key 键
* @param value 值
* @param timeout 超时时间
* @param timeout 超时时间单位
*/
public void set(String key, String value, long timeout, TimeUnit timeUnit) {
this.redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 获取值
*
* @param key 键
* @return 获取值
*/
public String get(String key) {
return this.redisTemplate.opsForValue().get(key);
}
/**
* 删除
*
* @param key 健
*/
public void delete(String key) {
this.redisTemplate.delete(key);
}
/**
* 当不存在的时候设置值,
*
* @param key 键
* @param value 值
* @param expireSeconds 超时时间(单位 秒)
* @return 成功 返回 OK
*/
public boolean setIfNotExists(String key, String value, long expireSeconds) {
return this.setIfNotExists(key, value, expireSeconds, TimeUnit.SECONDS);
}
/**
* 当不存在的时候设置值,
*
* @param key 键
* @param value 值
* @param expire 超时时间
* @param timeUnit 超时单位
* @return 成功 返回 OK
*/
public boolean setIfNotExists(String key, String value, long expire, TimeUnit timeUnit) {
final long finalExpire = this.getExpireSeconds(expire, timeUnit);
String status = this.redisTemplate.execute((RedisCallback<String>) connection -> {
Object nativeConnection = connection.getNativeConnection();
if (nativeConnection instanceof JedisCluster) {
JedisCluster jedisCluster = (JedisCluster) nativeConnection;
// 只有可以不存在是才设置,并且设置超时时间
return jedisCluster.set(key, value, "nx", "ex", finalExpire);
} else {
Jedis jedis = (Jedis) nativeConnection;
// 只有可以不存在是才设置,并且设置超时时间
return jedis.set(key, value, "nx", "ex", finalExpire);
}
});
if (StringUtils.isEmpty(status)) {
return false;
} else {
return "OK".equals(status);
}
}
/**
* 时间转换 转为 秒
*
* @param expire 时间
* @param timeUnit 单号
* @return 返回 秒
*/
private long getExpireSeconds(long expire, TimeUnit timeUnit) {
//1秒(s) =100厘秒(cs)= 1000 毫秒(ms) = 1,000,000 微秒(μs)
// = 1,000,000,000 纳秒(ns) = 1,000,000,000,000 皮秒(ps)
//=1,000,000,000,000,000飞秒(fs)=1,000,000,000,000,000,000仄秒(zs)
// =1,000,000,000,000,,000,000,000幺秒(ys)=1,000,000,000,000,000,000,000,000渺秒(as)
switch (timeUnit) {
case DAYS:
expire = expire * 24 * 60 * 60;
break;
case HOURS:
expire = expire * 60 * 60;
break;
case MINUTES:
expire = expire * 60;
break;
case MILLISECONDS:
expire = expire / 10 ^ 3;
break;
case MICROSECONDS:
expire = expire / 10 ^ 6;
break;
case NANOSECONDS:
expire = expire / 10 ^ 9;
break;
default:
break;
}
return expire;
}
}
3、redis 分布锁实现类
@Component
public class RedisLock {
/**
* redis操作的类
*/
@Autowired
private RedisStringUtil redisStringUtil;
/**
* 加锁的值
*/
private static final String LOCK_VALUE = "TRUE";
/**
* 默认超时时间 10s
*/
private static final int TIME = 10;
/**
* 锁的前缀,命名空间
*/
private static final String PREFIX = "LOCKS:";
/**
* 加锁
*
* @param key 键
*/
public boolean lock(String key) {
return this.redisStringUtil.setIfNotExists(PREFIX.concat(key), LOCK_VALUE, TIME);
}
/**
* 加锁,有超时时间(建议)
* 避免解锁失败导致死锁
*
* @param key 键
* @param time 超时时间(默认 秒)
*/
public boolean lock(String key, long time) {
return this.redisStringUtil.setIfNotExists(PREFIX.concat(key), LOCK_VALUE, time);
}
/**
* 加锁,有超时时间(建议)
* 避免解锁失败导致死锁
*
* @param key 键
* @param time 超时时间
* @param unit 超时单位
*/
public boolean lock(String key, long time, TimeUnit unit) {
return this.redisStringUtil.setIfNotExists(PREFIX.concat(key), LOCK_VALUE, time, unit);
}
/**
* 解锁
*
* @param key 键
*/
public void unlock(String key) {
this.redisStringUtil.delete(PREFIX.concat(key));
}
4、使用方式
@Autowired
private RedisLock redisLock;
public void test() {
String key = "lock_";
if (this.redisLock.lock(key)) {
try {// 需要加锁的代码块
} finally {
this.redisLock.unlock(key);
}
}
}