Skip to content

Commit 061a743

Browse files
committed
feat: add redis-distributed-lock.md
利用 Redis String 实现分布式锁
1 parent 023aba4 commit 061a743

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ Redis 基础的数据结构有 5 种,分别是:
3939
每一种数据结构都有它对应的实践场景,下面几个小节会就这几种数据结构展开讨论,也欢迎各位开发朋友来分享更多的应用案例。
4040

4141
### 字符串
42+
- [说说分布式锁的实现方式?](/docs/redis-distributed-lock.md)
4243

4344
### 列表
4445
- 如何利用 Redis List 实现异步消息队列?
4546

4647
### 哈希
48+
- [登录会话,用 Redis 该怎么做?](/docs/redis-hash-session-token.md)
4749

4850
### 集合
4951

docs/redis-distributed-lock.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# 使用 Redis String 实现分布式锁
2+
3+
4+
## 代码实现
5+
1. Python 版本
6+
7+
```python
8+
import random
9+
import string
10+
import time
11+
12+
from redis import Redis
13+
14+
15+
def generate_random_value():
16+
return ''.join(random.sample(string.ascii_letters + string.digits, 32))
17+
18+
19+
# 设定默认过期时长为 10s
20+
DEFAULT_TIMEOUT = 10
21+
22+
23+
class DistributedLock:
24+
def __init__(self, client: Redis, key: str):
25+
self.client = client
26+
self.key = key
27+
28+
def acquire(self, timeout=DEFAULT_TIMEOUT) -> bool:
29+
"""尝试获取锁"""
30+
res = self.client.set(self.key, generate_random_value(), ex=timeout, nx=True) # ex 表示过期时长秒数,nx 表示 key 不存在时才设置
31+
return res is True
32+
33+
def release(self) -> bool:
34+
"""尝试释放锁"""
35+
return self.client.delete(self.key) == 1
36+
37+
38+
if __name__ == '__main__':
39+
redis = Redis(decode_responses=True)
40+
lock = DistributedLock(redis, 'bingo_distributed_lock')
41+
42+
print(lock.acquire(10)) # True
43+
print(lock.acquire(10)) # False
44+
45+
time.sleep(10)
46+
print(lock.acquire()) # True
47+
print(lock.release()) # True
48+
49+
print(lock.acquire()) # True
50+
```
51+
52+
2. Java 版本
53+
54+
```java
55+
import redis.clients.jedis.Jedis;
56+
import redis.clients.jedis.params.SetParams;
57+
58+
import java.util.UUID;
59+
import java.util.concurrent.TimeUnit;
60+
61+
62+
public class DistributedLock {
63+
64+
private Jedis client;
65+
private String key;
66+
67+
public DistributedLock(Jedis client, String key) {
68+
this.client = client;
69+
this.key = key;
70+
}
71+
72+
private String generateRandomValue() {
73+
return UUID.randomUUID().toString().replaceAll("-", "");
74+
}
75+
76+
77+
public boolean acquire(int timeout) {
78+
SetParams params = new SetParams().ex(timeout).nx();
79+
return client.set(key, generateRandomValue(), params) != null;
80+
}
81+
82+
public boolean acquire() {
83+
int timeout = 10;
84+
return acquire(timeout);
85+
}
86+
87+
public boolean release() {
88+
return client.del(key) == 1;
89+
}
90+
91+
public static void main(String[] args) throws InterruptedException {
92+
Jedis jedis = new Jedis();
93+
DistributedLock lock = new DistributedLock(jedis, "bingo_distributed_lock");
94+
95+
System.out.println(lock.acquire(10)); // true
96+
System.out.println(lock.acquire(10)); // false
97+
98+
TimeUnit.SECONDS.sleep(10);
99+
System.out.println(lock.acquire()); // true
100+
System.out.println(lock.release()); // true
101+
102+
System.out.println(lock.acquire()); // true
103+
}
104+
}
105+
```

0 commit comments

Comments
 (0)