码迷,mamicode.com
首页 > 其他好文 > 详细

redis实现分布式锁

时间:2019-09-29 18:14:27      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:static   res   png   val   lse   其他   ring   l命令   bool   

1.锁的处理

  • 单应用中(单进程多线程情况)锁的处理:
    • synchronized
    • lock
  • 分布式应用中锁的处理:
    • 数据库乐观锁;
    • 基于zookeeper的分布式锁;
    • 基于redis的分布式锁

2.分布式锁需要注意事项

  • 互斥性: 在任意时刻,只有一个客户端能持有锁
  • 同一性:   加锁和解锁必须是同一个客户端,客户端自己不能把别的客户端加的锁给解了
  • 避免死锁:  即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁 

3.获取锁

方式一:使用set命令实现

技术图片

 

 

 代码如下:

/**
     * 使用redis的set命令实现获取分布式锁
     * @param lockKey       可以就是锁
     * @param requestId        请求ID,保证同一性
     * @param expireTime    过期时间,避免死锁
     * @return
     */
    public static boolean getLock(String lockKey,String requestId,int expireTime) {
        //NX:保证互斥性
        String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);
        if("OK".equals(result)) {
            return true;
        }
        
        return false;
    }

 

方式二:使用setnx命令,这里使用synchronized保证方法的原子性
1 public static synchronized boolean Lock2(String lockKey,String requestId,int expireTime) {
2         Long result = jedis.setnx(lockKey, requestId);
3         if(result == 1) {
4             jedis.expire(lockKey, expireTime);
5             return true;
6         }
7 
8         return false;
9     }

4.释放锁

方式一:使用del命令

    /**
     * 释放分布式锁
     * @param lockKey
     * @param requestId
     */
    public static void releaseLock(String lockKey,String requestId) {
        if (requestId.equals(jedis.get(lockKey))) {
            jedis.del(lockKey);
        }
    }

方式二:使用Lua脚本

public static boolean releaseLock(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 (result.equals(1L)) {
            return true;
        }
        return false;
    }

 

redis实现分布式锁

标签:static   res   png   val   lse   其他   ring   l命令   bool   

原文地址:https://www.cnblogs.com/kiwi-deng/p/11608874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!