介绍
复述,分布式锁有哪些?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!
我们通常使用的同步或者锁都是线程锁,对同一个JVM进程内的多个线程有效。因为锁的本质是内存中存放一个标记,记录获取锁的线程是谁,这个标记对每个线程都可见,然而我们启动的多个订单服务,就是多个JVM,内存中的锁显然是不共享的,每个JVM进程都有自己的锁,自然无法保证线程的互斥了,这个时候我们就需要使用到分布式锁了。常用的有三种解决方案:1。基于数据库实现2。基于管理员的临时序列化节点实现3。复述,实现。本文我们介绍的就是复述的实现方式。
<强> 强>
<强> 1)强> <强>多进程可见强>
复述本身就是基于JVM之外的,因此满足多进程可见的要求。
<强> 2)强> <>强互斥强>
复述的setnx实现,只有第一次执行的才会成功并返回1,其它情况返回0。
释放锁
释放锁其实只需要把锁的钥匙删除即可,使用▽xxx指令,不过,如果在我们执行del之前,服务突然宕机,那么锁就永远无法删除了,所以我们可以通过setex命令设置过期时间即可。
进口java.util.UUID;进口org.slf4j.Logger;进口org.slf4j.LoggerFactory;进口org.springframework.beans.factory.annotation.Autowired;进口org.springframework.stereotype.Component;进口redis.clients.jedis.Jedis;进口redis.clients.jedis.JedisPool;/* * *第一种分布式锁*/@Componentpublic类RedisService{私人最后日志记录器=LoggerFactory.getLogger (this.getClass ()); @ autowired JedisPool JedisPool;//获取锁之前的超时时间(获取锁的等待重试时间) 私人长acquireTimeout=5000;//获取锁之后的超时时间(防止死锁) 私人int超时=10000;/* * *获取分布式锁 * @return锁标识*/lockName公共布尔getRedisLock(字符串,字符串val) { 能能=零;尝试{ 能=jedisPool.getResource ();//1 .计算获取锁的时间 长endTime=System.currentTimeMillis () + acquireTimeout;//2 .尝试获取锁 而(System.currentTimeMillis () & lt;endTime) {//3。获取锁成功就设置过期时间 如果能。setnx (lockName val)==1) { 能。到期(lockName超时/1000);返回true; } } }捕捉(异常e) { log.error (e.getMessage ()); 最后}{ returnResource(能); }返回false; }/* * *释放分布式锁 * @param lockName锁名称*/公共空间unRedisLock(字符串lockName) { 能能=零;尝试{ 能=jedisPool.getResource ();//释放锁jedis.del (lockName); }捕捉(异常e) { log.error (e.getMessage ()); 最后}{ returnResource(能); } }//===============================================公共字符串(字符串键){ 能能=零; 字符串值=https://www.yisu.com/zixun/null;尝试{ 能=jedisPool.getResource (); 值=jedis.get(关键); log.info(价值); }捕捉(异常e) { log.error (e.getMessage ()); 最后}{ returnResource(能); }返回值; } 公共空集(字符串,字符串值){ 能能=零;尝试{ 能=jedisPool.getResource (); 能。集(关键字,值); }捕捉(异常e) { log.error (e.getMessage ()); 最后}{ returnResource(能); } }/* * *关闭连接*/公共空间returnResource(能能){尝试{如果(能!=null) jedis.close (); }捕捉(异常e) { } } }
上面的分布式锁实现了,但是这时候还可能出现另外2个问题:
一:获取锁时
setnx获取锁成功了,还没来得及setex服务就宕机了,由于这种非原子性的操作,死锁又发生了。其实复述,提供了nx与前女友连用的命令。