实现分布式锁的三中方式
来源:互联网 发布:idc服务商网站php源码 编辑:程序博客网 时间:2024/04/28 03:54
1、数据库的乐观锁(版本号机制)
悲观锁与乐观锁
2、基于Redis的分布式锁
加锁
public class RedisTool { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; /** * 尝试获取分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间 * @return 是否获取成功 */ public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } }
我们加锁就一行代码:jedis.set(String key, String value, String nxxx, String expx, int time),这个set()方法一共有五个形参:
- 第一个为key,我们使用key来当锁,因为key是唯一的。
- 第二个为value,我们传的是requestId,很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为requestId,我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。requestId可以使用UUID.randomUUID().toString()方法生成。
- 第三个为nxxx,这个参数我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;
- 第四个为expx,这个参数我们传的是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。
- 第五个为time,与第四个参数相呼应,代表key的过期时间。
总的来说,执行上面的set()方法就只会导致两种结果:1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。2. 已有锁存在,不做任何操作。
解锁public class RedisTool { private static final Long RELEASE_SUCCESS = 1L; /** * 释放分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @return 是否释放成功 */ public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) { 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, Collections.singletonList(lockKey), Collections.singletonList(requestId)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } }
第二行代码,我们将Lua代码传到jedis.eval()方法里,并使参数KEYS[1]赋值为lockKey,ARGV[1]赋值为requestId。eval()方法是将Lua代码交给Redis服务端执行。
那么这段Lua代码的功能是什么呢?其实很简单,首先获取锁对应的value值(requestId),检查是否与requestId相等,如果相等则删除锁(解锁)。那么为什么要使用Lua语言来实现呢?因为要确保上述操作是原子性的。
3、基于zookeeper的分布式锁阅读全文
0 0
- 实现分布式锁的三中方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁实现的三种方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁的三种实现方式
- 分布式锁解决并发的三种实现方式
- 分布式锁的三种实现方式 / 分布式锁原理及实现方式 / 分布式锁1 Java常用技术方案
- 分布式锁的实现方式
- 在排序好的数组中添中一个数字
- GithubPages教程 在GithubPages上搭建个人主页
- ubuntu 图片格式批量转换,批量处理
- tomcat日志分割
- 9轴传感器
- 实现分布式锁的三中方式
- opencv从多边形创建mask
- Git详解之基本原理
- c# out、ref、params使用
- 【清华集训2017模拟12.10】大佬的难题
- sickit-image windows 安装
- C语言可变参数和格式化输出
- spring中的scope详解
- JS判断用户使用的是手机还是电脑?