本文共 3033 字,大约阅读时间需要 10 分钟。
Redis 实现分布式锁,思路是使用 setnx 命令在 Redis 上创建相同的 Key,因为 Key 值不允许重复,哪个客户端能够创建成功,就能获取到锁,否则,就会进行等待,当释放锁后,就会通知客户端去争夺锁资源。
和 set 命令不同,set 如果设置相同的键,就会覆盖原来的值,返回 ok,而使用 setnx 命令,如果执行成功,则返回 1,表示成功获得锁,执行失败,返回 0,获得锁失败。
redis.clients jedis 2.9.0
public class RedisLock { private JedisPool jedisPool; private String redisKey = "redisKey"; public RedisLock(JedisPool jedisPool) { this.jedisPool = jedisPool; } public String getLock(Long acquireTime, Long timeOut) { Jedis con = null; try { //建立链接 con = jedisPool.getResource(); //定义key值 String value = UUID.randomUUID().toString(); //获取锁之后设置的超时时间,防止死锁 int expire = (int) (timeOut / 1000); Long endTime = System.currentTimeMillis() + acquireTime; while (System.currentTimeMillis() < endTime) { //获取锁 if (con.setnx(redisKey, value) == 1) { //设置超时时间防止死锁 con.expire(redisKey, expire); return value; } } } catch (Exception e) { e.printStackTrace(); } finally { if (con != null) { con.close(); } } return null; } public void unLock(String val) { Jedis con = null; //自己删除自己创建的锁 con = jedisPool.getResource(); try { if (val.equals(con.get(redisKey))) { con.del(redisKey); System.out.println(Thread.currentThread().getName()+"释放锁成功>>>"); } } catch (Exception e) { e.printStackTrace(); } finally { if (con != null) { con.close(); } } }}
public class LockService { private static JedisPool pool = null; static { JedisPoolConfig config = new JedisPoolConfig(); //最大连接数 config.setMaxTotal(200); //最大空闲数 config.setMaxIdle(50); //最大等待时间 config.setMaxWaitMillis(1000 * 100); //是否需要验证 config.setTestOnBorrow(true); pool = new JedisPool(config, "10.13.9.117", 6379, 5000); } private RedisLock lock = new RedisLock(pool); public void test() { String val = lock.getLock(5000L, 5000L); if (val == null) { System.out.println(Thread.currentThread().getName() + "获取锁失败!"); return; } System.out.println(Thread.currentThread().getName() + "成功获取锁:" + val); lock.unLock(val); }}
public class Test { public static void main(String[] args) { LockService lockService = new LockService(); for (int i = 0; i < 20; i++) { new Thread(()->lockService.test()).start(); } }}
https://github.com/huangliangyun/Spring-Boot-2.X/tree/master/spring-boot-redis
公众号:【星尘Pro】
github:
推荐阅读
转载地址:http://jyfsi.baihongyu.com/