在一些大的项目中,为了保持一致性,就会使用到分布式锁,今天我们要说的就是基于Redis实现分布式锁,跟我一起来看看吧。
为什么需要分布式锁?
在java中单进程多线程的情况下,为了防止多个线程共同竞争同一个资源,所以需要锁,java中有显示锁和隐式锁来保证,而在多进程的情况下,普通的锁无法满足要求,因此,我们就需要分布式锁。
下面我们就以这个例子来看看redis分布式锁到底是怎么实现的吧。
依赖导入:
首先我们需要在pom.xml文件加入以下代码:
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
然后才是实例代码的编写:
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()方法一共有五个形参:
1.key:我们使用key当锁,因为key是唯一的。
2.value:我们传的是requestId,很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为requestId,我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。requestId可以使用UUID.randomUUID().toString()方法生成。
3.nxxx:这里我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;
4.expx:这个参数我们传的是PX,意是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。
5.time:与第四个参数相呼应,代表key的过期时间。
执行上面的set()方法只有两种结果:
1. 当前没有锁,那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。
2.已有锁,不做任何操作。
总结
使用Redis分布式锁不是一个太好选择,Redis设计初衷并不是来满足分布式锁的需求.对于需求性能的分布式锁应用来说它太重了且成本高;对于需求正确性的应用来说它又不够安全.所以如果你的应用只需要高性能的分布式锁并且不要求多高的正确性,那么建议使用单节点的Redis分布式锁就足够了。
以上就是本文的所有内容了,更多Java常见问答内容请关注我们的网站了解吧。