redis分布式锁的实现

 
 

   本文为博主原创文章,转载请附带博客地址:https://www.cnblogs.com/xbjhs/p/11041221.html

     这个分布式锁满足:

  1. 互斥性。在任意时刻,只有一个客户端能持有锁。
  2. 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
  3. 解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了

1.jedisPool

package com.test;


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;


/**
 * Description:redis线程池 
* *
@author: * @date 2019-06-17 11:04 * @Param: * @Return: */ public class JedisPoolUtil { /** * 被volatile修饰的变量不会被本地线程缓存,对该变量的读写都是直接操作共享内存 */ private static volatile JedisPool jedisPool = null; private JedisPoolUtil() { } public static JedisPool getJedisPoolInstance() { if (null == jedisPool) { synchronized (JedisPoolUtil.class) { if (null == jedisPool) { JedisPoolConfig poolConfig = new JedisPoolConfig(); // 设置最大实例总数 poolConfig.setMaxTotal(1000); //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。 poolConfig.setMaxIdle(100); //表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException; poolConfig.setMaxWaitMillis(100 * 1000); //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的 poolConfig.setTestOnBorrow(true); // 实例在还给pool时,是否提前进行validate操作 poolConfig.setTestOnReturn(true); jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379); } } } return jedisPool; } public static void release(Jedis jedis) { if (null != jedis) { jedis.close(); } } }
 
 

 

 
2.获取redis锁,解锁的测试类
package com.test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Arrays;
import java.util.UUID;

/**
 * Description:redis锁实现类 
* *
@author: * @date 2019-06-17 11:43 * @Param: * @Return: */ public class TestPool { public static void main(String[] args) { Jedis jedis = null; try { RedisLock redisLock = new RedisLock("123421342134"); //获取锁 redisLock.getRedisLock(); //doSomething //释放锁 redisLock.unlock(); } catch (Exception e) { System.out.println("获取||释放redis锁异常" + e); } finally { if (null != jedis) { JedisPoolUtil.release(jedis); } } } }

 

package com.test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Arrays;
import java.util.UUID;

/**
 * Description:redis锁 
* *
@author: * @date 2019-06-17 17:07 * @Param: * @Return: */ public class RedisLock { public static final String SET_SUCCESS = "OK"; private String key; private String val; public RedisLock(String key) { this.key = key; this.val = UUID.randomUUID().toString(); } /** * 加锁 */ public void getRedisLock() { Jedis jedis = getResource(); /** *第三个参数是NX,意思是SET IF NOT EXIST,即当key不存在时,进行set操作;若key已经存在,则不做任何操作; *第四个参数是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。 *第五个为time,与第四个参数相呼应,代表key的过期时间。 */ String response = jedis.set(key, val, "NX", "PX", 20000); if (!SET_SUCCESS.equals(response)) { //抛出自定义异常 } if (null != jedis) { JedisPoolUtil.release(jedis); } } /** * 获取实例 */ public static Jedis getResource() { JedisPool jedisPool = JedisPoolUtil.getJedisPoolInstance(); JedisPool jedisPool2 = JedisPoolUtil.getJedisPoolInstance(); System.out.println(jedisPool == jedisPool2); Jedis jedis = jedisPool.getResource(); return jedis; } /** * 解锁 */ public void unlock() { Jedis jedis = getResource(); jedis.eval("if redis.call('get',KEYS[1]) == ARGV[1] then \n return redis.call('del',KEYS[1]) \n else return 0 \n end", Arrays.asList(key), Arrays.asList(val)); System.out.println("释放锁成功"); if (null != jedis) { JedisPoolUtil.release(jedis); } } }

 

3.pom依赖


redis.clients
jedis
2.8.2

  4.截图

redis分布式锁的实现_第1张图片

你可能感兴趣的:(redis分布式锁的实现)