redis分布式锁的简单实现原理

 

1.前言

       并发的解决方式是锁,那么分布式并发解决方式则是分布式锁。本文将从原理解析redis分布式锁是如何一步一步实现的 

2.分布式锁的实现及问题解决

       redis分布式锁完全建立在redis为单线程上,因为redis是单线程的,放在队列中的请求是要一条一条执行的。

       redis加锁:使用setnx方法进行加锁;setnx方法设置key-value和超时时间(重点:key,value,超时时间)

1)redis的setnx的为原子操作,如果存在key则返回失败,否则写入成功,获得key锁

2)超时时间:必须设置!如果获得锁的线程由于某种原因一直不释放锁,那么这个锁就永远无法被别的线程获取了,而且还可能导致死锁的

3)超时时间导致的问题:a).如果线程1获得锁,但是任务还没执行完,锁失效(删除key-value),这时线程2就可以获得锁,会导致线程1和线程2同时操作某些资源,导致脏数据产生。解决方法是设置一个监听,当任务没有执行完时,给锁增加超时时间

b).还是上面的例子,线程1执行完任务后,会去释放锁(删除key-value),但是此时的锁已经不是线程1的锁了,是线程2的锁,这样又可能导致其他的问题。解决方式是给每个线程的锁设定唯一标志,要删也只能删自己的那个锁,这时就使用到了value这个值了。每次获取锁时,将value存在threadlocal中,当要删除锁的时候,先获取redis中的value,判断和threadlocal中的value是否一致,是则释放锁,否则不释放。但是这又会产生一个问题,获取判断释放是3步操作,非原子操作,执行中value的值随时可能改变。这时就要使用lua脚本了,将获取判断释放3个操作放在一起,再给redis执行就是原子性的了。

 

以上是redis实现互斥锁的原理以及解决问题的办法,如果看懂了的话,可以研究下链接里的实际使用方式:https://blog.csdn.net/wutengfei_java/article/details/100699538(转载)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴回答你的问题!关于redis分布式锁的原理及实现方法,在分布式系统中提供一种比较有效的控制并发访问的方法。具体实现方法主要是通过redis中的setnx命令来实现。当一个客户端第一次请求获取锁时,通过setnx设置一个唯一标识符作为锁,如果返回值为1,则表示获取锁成功,否则获取锁失败。Java代码示例如下: ``` public class RedisLock { private final static String LOCK_KEY = "redis_lock";//锁的键值 private final static int LOCK_EXPIRE = 3000;//锁的过期时间,单位毫秒 private JedisPool jedisPool;//Jedis连接池 public RedisLock(JedisPool jedisPool) { this.jedisPool = jedisPool; } /** * 加锁 * @return */ public boolean lock() { Jedis jedis = null; try { jedis = jedisPool.getResource(); long expires = System.currentTimeMillis() + LOCK_EXPIRE + 1; String expiresStr = String.valueOf(expires); if (jedis.setnx(LOCK_KEY, expiresStr) == 1) { jedis.expire(LOCK_KEY, LOCK_EXPIRE);//设置过期时间,避免锁忘记释放导致死锁 return true; } String currentValueStr = jedis.get(LOCK_KEY); if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) { String oldValueStr = jedis.getSet(LOCK_KEY, expiresStr); if (oldValueStr != null && oldValueStr.equals(currentValueStr)) { jedis.expire(LOCK_KEY, LOCK_EXPIRE);//设置过期时间,避免锁忘记释放导致死锁 return true; } } } catch (Exception e) { e.printStackTrace(); } finally { if (jedis != null) { jedis.close(); } } return false; } /** * 释放锁 */ public void unlock() { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.del(LOCK_KEY); } catch (Exception e) { e.printStackTrace(); } finally { if (jedis != null) { jedis.close(); } } } } ``` 以上就是关于redis分布式锁简单原理及Java代码实现示例,希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值