分布式锁的实现(java)

南楼画角 提交于 2021-02-17 18:33:50

  当对接第三方接口时,往往会碰到同一时间发送了大量相同的请求,这个时候或许就是第三方发送接口的失误了。而我们需要做的就是针对这个情况来强化我们的系统。这个时候就需要用到分布式锁。让这些请求只有一个能发送进来。

分布式锁的实现一般有三种:

  1. 基于数据库的乐观锁;
  2. 基于redis的分布式锁;
  3. 基于zookeeper的分布式锁。

  这里我们讲的是第二种:基于redis的分布式锁的原理以及实现。

下面是代码的实现:

public class DistributeLock {
    /**
     * setnx(key,value):如果key-value存在,缓存成功并返回1,否则返回0.
     * getset(key,value):返回旧的value,然后更新旧的value为新的value.
     * expire(key,seconds):设置key的过期时间为seconds秒.
     * get(key):获取key对应的value,不存在返回nil.
     */

    private final static long expire = 1000; // 设置锁的过期时间

    public static boolean getLockByRedis(Jedis jedis,String lock){
        boolean success = false;
        long flag = jedis.setnx(lock, String.valueOf(System.currentTimeMillis() + expire + 1));
        // 获取分布式锁成功
        if (flag == 1) {
            success = true;
        }else{ // 可能其他线程持有锁,也有可能是锁超时
            long getVale = Long.valueOf(jedis.get(lock));
            if (getVale < System.currentTimeMillis()) { //超时
                String oldValue = jedis.getSet(lock,String.valueOf(System.currentTimeMillis() + expire + 1));
                if (oldValue != null) {
                    // 被其他线程抢占
                    if (Long.valueOf(oldValue) == getVale) {
                        success = false;
                    }else{
                        success = true;
                    }
                }

            }else{
                success = false;
            }
        }
        return success;
    }

    /**
     * 谁上锁,谁释放
     * @param jedis
     * @param lock
     */
    public static void releaseLock(Jedis jedis,String lock) {
        if (System.currentTimeMillis() <  Long.valueOf(jedis.get(lock))) {
            jedis.del(lock);
        }
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!