成功的路上总是离不开贵人的帮助,名师的指点和小人的刺激。

莫怕,过了桥,就翻篇了

基于redis实现分布式锁

相对于利用数据库实现分布式锁,利用redis来实现分布式锁,有以下几个优点

   优点:

1.可以集群部署的,可以解决单点问题。

2.自带过期时间可以解决死锁问题。

 可靠性介绍

  1. 互斥性。在任意时刻,只有一个客户端能持有锁。
  2. 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
  3. 具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
  4. 解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。

 

利用redis语句加锁。

 set key value nx ex 2

解锁

delete key 

 

问题所在:

虽然可以加入失效时间,一旦到了时间会自动删除锁,但是失效时间我设置多长时间为好?如何设置的失效时间太短,方法没等执行完,锁就自动释放了,那么就会产生并发问题。如果设置的时间太长,其他获取锁的线程就可能要平白的多等一段时间。这个问题使用数据库实现分布式锁同样存在。

 

package com.test;

import redis.clients.jedis.Jedis;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by edison on 2019/2/4.
 */
public class RedisJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("192.168.43.150");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: "+jedis.ping());

        ConcurrentHashMap cMap = new ConcurrentHashMap();
        cMap.put("key1", "\"abc\"");
        cMap.put("key2", "\"def\"");
        cMap.put("key3", "\"ghk\"");
        System.out.println(cMap.toString());

        StringBuffer sb = new StringBuffer();
        sb.append("local lockKeys = " + cMap.toString() + " ");
        sb.append("local flag = 1 ");
        sb.append("for i,v in pairs(lockKeys) do ");
        sb.append("  local result = redis.call(\"set\",i, v,\"nx\",\"ex\", 20) ");
        sb.append("if type(result) ~= \"table\" then" );
        sb.append("  flag = 0 ");
        sb.append(" break ");
        sb.append(" end ");
        sb.append(" end ");
        sb.append(" return flag ");
        System.out.println(sb.toString());
       Long eval = (Long) jedis.eval(sb.toString());
        System.out.println(eval);
        System.out.println("redis设置成功");


        StringBuffer sb2 = new StringBuffer();
        sb2.append("local lockKeys = " + cMap.toString() + " ");
        sb2.append("for i,v in pairs(lockKeys) do ");
        sb2.append("  redis.call(\"del\",i) ");
        sb2.append(" end ");

        Object eval1 = jedis.eval(sb2.toString());
        System.out.println("redis请除成功");


    }
}

 

posted on 2019-03-25 15:53  痞子陈2016  阅读(248)  评论(0编辑  收藏  举报

导航