逍遥谷

记录日常的点点滴滴

0%

Redis分布式锁

Redisson

Redis 官方给出了以上两种基于 Redis 实现分布式锁的方法,详细说明可以查看:https://redis.io/topics/distlock

Github: https://github.com/redisson/redisson

自己Java实现

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
package xxx;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import java.util.Collections;

/**
* <p>Used jedis 3.1.0</p>
* @see Jedis
*/
public class RedisDistributedLock {

private static final String LOCK_SUCCESS = "OK";
private static final Long UNLOCK_SUCCESS = 1L;
private static final long DEFAULT_MAX_LOCK_TIME = 300000L;
public static final String DELETE_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

private Jedis jedis;

private String key;

private long lockTime;

private RedisDistributedLock(Jedis jedis, String key, long lockTime) {
this.jedis = jedis;
this.key = key;
this.lockTime = lockTime;
}

public static RedisDistributedLock build(Jedis jedis, String key) {
return build(jedis, key, DEFAULT_MAX_LOCK_TIME);
}

public static RedisDistributedLock build(Jedis jedis, String key, long lockTime) {
return new RedisDistributedLockV1(jedis, key, lockTime);
}

public boolean lock() {
return lock(0, 0L);
}

public boolean lock(int retryTimes, long retryIntervalTimeMillis) {
int times = retryTimes + 1;
for (int i = 0; i < times; i++) {
SetParams setParams = SetParams.setParams();
setParams.nx().ex((int) (lockTime / 1000L));
String result = jedis.set(key, String.valueOf(key.hashCode()), setParams);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
if (retryIntervalTimeMillis > 0) {
try {
Thread.sleep(retryIntervalTimeMillis);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
break;
}
}
if (Thread.currentThread().isInterrupted()) {
break;
}
}
return false;
}

public boolean unlock() {
Object result = jedis.eval(DELETE_SCRIPT, Collections.singletonList(key), Collections.singletonList(String.valueOf(key.hashCode())));
return UNLOCK_SUCCESS.equals(result);
}

}