惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Jina AI
Jina AI
博客园 - 司徒正美
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
美团技术团队
腾讯CDC
博客园 - Franky
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
aimingoo的专栏
aimingoo的专栏
博客园_首页
V
V2EX
Martin Fowler
Martin Fowler
T
The Blog of Author Tim Ferriss

祈雨的笔记

安全多方计算MPC spark原理解析 kueue执行源码分析 spark on k8s执行源码分析 spark-operator源码解析 系统压测遇到的缓存击穿问题 我的世界PC与安卓联机 蚂蚁金服流量投放平台的AIG改造 G1大对象致Old区占用率高 日志打印导致接口响应率下跌分析 Groovy加载类导致OOM分析 ERROR日志打印导致CPU满载 记OceanBase死锁超时 应用发版期间服务响应超时 Ark Serverless初探 系统优化复盘一二三 The user specified as a definer does not exist Kong网关初探 API网关选型调研 CPU火焰图常用工具 配置中心选型调研 root操作Nginx导致用户组错误 基于Proxifier使用代理 FastJSON字段智能匹配踩坑 Nacos初探 记一次Nginx服务器CPU满荷载故障 基于券系统分库分表的思考 limit不参与SQL成本计算致索引失效 Linux常用性能监控命令 golang低版本http2偶现400
基于redis的分布式锁
祈雨的笔记 · 2018-08-21 · via 祈雨的笔记

锁实现代码

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
public class RedisLock {

private final Logger log = LoggerFactory.getLogger(RedisLock.class);
private static final Long RELEASE_SUCCESS = 1L;

private String lockKey;
private RedisConnectionFactory connectionFactory;

public RedisLock(RedisConnectionFactory connectionFactory, String lockKey) {
this.connectionFactory = connectionFactory;
this.lockKey = lockKey;
}






public synchronized long lock(long milliTimeout) {
log.debug("开始执行加锁 ==> {}",lockKey);
try (Jedis jedis = getJedis()) {




long lockValue = new Random(System.currentTimeMillis()).nextLong();


String result = jedis.set(lockKey, String.valueOf(lockValue), "NX", "PX", milliTimeout);
if("OK".equals(result)) {
return lockValue;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return -1;
}




public synchronized boolean unlock(Long lockValue) {
boolean unlockSuccess = false;
log.debug("执行解锁 ==> {}",lockKey);
try (Jedis jedis = getJedis()) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, 1, lockKey.toString(), lockValue.toString());
if (RELEASE_SUCCESS.equals(result)) {
log.debug("解锁成功 ==> {}",lockKey);
unlockSuccess = true;
}
} catch (Exception e) {
log.error(e.getMessage(),e);
throw new RuntimeException(e);
}
return unlockSuccess;
}





private Jedis getJedis() {
Field jedisField = ReflectionUtils.findField(JedisConnection.class, "jedis");
ReflectionUtils.makeAccessible(jedisField);
Jedis jedis = (Jedis) ReflectionUtils.getField(jedisField, connectionFactory.getConnection());
return jedis;
}

}

使用

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

@Autowired
private RedisConnectionFactory connectionFactory;

public void testLock() {


String key = "testLock-redis-lock";
RedisLock lock = new RedisLock(connectionFactory, key);


long value = lock.lock(10000);
if(value != -1) {
log.debug("竞争锁成功 ==> {}",key);
try {

} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
lock.unlock(value);
}
} else {
log.debug("竞争锁失败 ==> {}",key);
}
}

redisson

采用成熟的框架redisson,封装好的方法则可以使用。

github

文档

分布式锁和同步器