一、简介
Redis 实现分布式锁,思路是使用 setnx 命令在 Redis 上创建相同的 Key,因为 Key 值不允许重复,哪个客户端能够创建成功,就能获取到锁,否则,就会进行等待,当释放锁后,就会通知客户端去争夺锁资源。
和 set 命令不同,set 如果设置相同的键,就会覆盖原来的值,返回 ok,而使用 setnx 命令,如果执行成功,则返回 1,表示成功获得锁,执行失败,返回 0,获得锁失败。
二、代码实现
1、添加 maven 依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2、分布式锁的实现
public class RedisLock {
private JedisPool jedisPool;
private String redisKey = "redisKey";
public RedisLock(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
public String getLock(Long acquireTime, Long timeOut) {
Jedis con = null;
try {
//建立链接
con = jedisPool.getResource();
//定义key值
String value = UUID.randomUUID().toString();
//获取锁之后设置的超时时间,防止死锁
int expire = (int) (timeOut / 1000);
Long endTime = System.currentTimeMillis() + acquireTime;
while (System.currentTimeMillis() < endTime) {
//获取锁
if (con.setnx(redisKey, value) == 1) {
//设置超时时间防止死锁
con.expire(redisKey, expire);
return value;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}
return null;
}
public void unLock(String val) {
Jedis con = null;
//自己删除自己创建的锁
con = jedisPool.getResource();
try {
if (val.equals(con.get(redisKey))) {
con.del(redisKey);
System.out.println(Thread.currentThread().getName()+"释放锁成功>>>");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}
}
}
public class LockService {
private static JedisPool pool = null;
static {
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数
config.setMaxTotal(200);
//最大空闲数
config.setMaxIdle(50);
//最大等待时间
config.setMaxWaitMillis(1000 * 100);
//是否需要验证
config.setTestOnBorrow(true);
pool = new JedisPool(config, "10.13.9.117", 6379, 5000);
}
private RedisLock lock = new RedisLock(pool);
public void test() {
String val = lock.getLock(5000L, 5000L);
if (val == null) {
System.out.println(Thread.currentThread().getName() + "获取锁失败!");
return;
}
System.out.println(Thread.currentThread().getName() + "成功获取锁:" + val);
lock.unLock(val);
}
}
public class Test {
public static void main(String[] args) {
LockService lockService = new LockService();
for (int i = 0; i < 20; i++) {
new Thread(()->lockService.test()).start();
}
}
}
三、测试结果
四、代码下载
https://github.com/huangliangyun/Spring-Boot-2.X/tree/master/spring-boot-redis
ABOUT
公众号:【星尘Pro】
github:https://github.com/huangliangyun