发布于 

redis 分布式锁实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
* 获取锁
*
* @param lockKey 锁key
* @param value 锁值 一般随机生成
* @param expireTime:单位-秒
* @return 成功猎取锁返回true
*/
public boolean getLock(String lockKey, String value, int expireTime) {
try {
String script = "if redis.call('setNx',KEYS[1],ARGV[1]) then if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end end";
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
Object result = this.redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value, expireTime);
if (SUCCESS.equals(result)) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return false;
}

/**
* 释放锁
*
* @param lockKey 锁key
* @param value 锁值 获取锁时随机生成的串
* @return
*/
public boolean releaseLock(String lockKey, String value) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
Object result = this.redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value);
if (SUCCESS.equals(result)) {
return true;
}
return false;
}

/**
* 获取查询锁,返回锁标识
*
* @param lockName 锁的key
* @param acquireTimeout 获取锁超时时间 ms
* @param timeout 锁的超时时间 ms
* @return 锁标识UUID
*/
public String lockWithTimeout(String lockName, int acquireTimeout, int timeout) {
// 随机生成一个value
String value = UUID.randomUUID().toString();
if(lockWithTimeout(lockName, value, acquireTimeout, timeout)) {
return value;
}
return null;
}

/**
* 获取查询锁
* @param lockName 锁的key
* @param requestId 请求标识码
* @param acquireTimeout 获取锁超时时间 ms
* @param timeout 锁的超时时间 ms
* @return
*/
public boolean lockWithTimeout(String lockName, String requestId, int acquireTimeout, int timeout) {
// 超时时间,上锁后超过此时间则自动释放锁
int lockExpire = timeout / 1000;

// 获取锁的超时时间,超过这个时间则放弃获取锁
long end = System.currentTimeMillis() + acquireTimeout;
while (System.currentTimeMillis() < end) {
if (getLock(lockName, requestId, lockExpire)) {
return true;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return false;
}

本站由 @binvv 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。