博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于Redis的简单分布式锁
阅读量:7228 次
发布时间:2019-06-29

本文共 4962 字,大约阅读时间需要 16 分钟。

  hot3.png

      在项目开发中,常常会碰到需要做lock锁的操作,而Redis又是最常用的分布式锁。在这提供一种简单的分布式锁实现,当然这里也有些考虑不周到,比如没实现公平与非公平锁、重入特性以及setNx及expire命令是分开的在极端(比如执行完A命令程序被kill -9了)造成死锁情况,没做redis集群情况下的高可用。

@Componentpublic class RedisOperation {    @Autowired    private RedisTemplate redisTemplate;    private static final long DEFAULT_EXPIRATION_TIMES = 600l;    public void set(final String key, final String value) {        this.set(key, value, DEFAULT_EXPIRATION_TIMES);    }    public void set(final String key, final String value, final long seconds) {        redisTemplate.execute(new RedisCallback() {            @Override            public Object doInRedis(RedisConnection connection) throws DataAccessException {                connection.setEx(redisTemplate.getStringSerializer().serialize(key), seconds, redisTemplate.getStringSerializer().serialize(value));                return null;            }        });    }    public boolean setNx(final String key, final String value, final long seconds) {        return redisTemplate.execute(new RedisCallback
() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { byte[] serializeKey = redisTemplate.getStringSerializer().serialize(key); boolean result = connection.setNX(serializeKey, redisTemplate.getStringSerializer().serialize(value)); if (result) { connection.expire(serializeKey, seconds); } return result; } }); } public String get(final String key) { return redisTemplate.execute(new RedisCallback
() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { byte[] byteKye = redisTemplate.getStringSerializer().serialize(key); if (connection.exists(byteKye)) { byte[] byteValue = connection.get(byteKye); String value = redisTemplate.getStringSerializer().deserialize(byteValue); return value; } return null; } }); } public boolean exists(final String key) { return redisTemplate.execute(new RedisCallback
() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { return connection.exists(redisTemplate.getStringSerializer().serialize(key)); } }); } public void delete(final String key) { redisTemplate.execute(new RedisCallback
() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { connection.del(redisTemplate.getStringSerializer().serialize(key)); return null; } }); }}@Componentpublic class DistributeLock { private static final Logger logger = LoggerFactory.getLogger(DistributeLock.class); public static final String REDIS_LOCK = "Demo:RedisLock:"; @Autowired private RedisOperation redisOperation; public boolean lock(String key, long timeout, long waitTimeout) { return lock(key, timeout, waitTimeout, true); } /** * * @param key * @param timeout key超时时间 单位:秒 * @param waitTimeout 等待获取锁时间 单位:毫秒 * @param force 是否强依赖锁 * @return * * @author hz15041240 * @date 2017-8-30 下午5:20:14 * @version */ public boolean lock(String key, long timeout, long waitTimeout, boolean forced) { String lockKey = generateLockKey(key); long nanoWaitForLock = TimeUnit.MILLISECONDS.toNanos(waitTimeout); long start = System.nanoTime(); try { do { if (redisOperation.setNx(lockKey, key, timeout)) { logger.debug("add distributed lock succeed; lockKey:{}", lockKey); return true; } TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(10, 80)); } while ((System.nanoTime() - start) < nanoWaitForLock); } catch (Exception e) { logger.error(String.format("add distributed lock exception lockKey:%s", lockKey), e); unlock(lockKey); return !forced; } return false; } public void unlock(String key) { String lockKey = generateLockKey(key); try { redisOperation.delete(lockKey); logger.debug("remove distributed lock key:{} succeed", lockKey); } catch (Exception e) { logger.error(String.format("unlock exception lockKey:{} ", lockKey), e); } } public boolean isLock(String key) { String lockKey = generateLockKey(key); return redisOperation.exists(lockKey); } private String generateLockKey(String key) { return new StringBuilder(50).append(REDIS_LOCK).append(key).toString(); }}

 

转载于:https://my.oschina.net/woter/blog/1845708

你可能感兴趣的文章
ionic $ionicSlideBoxDelegate 滑动框事件
查看>>
点击文字,把input type="radio"也选中
查看>>
第一章 Java多线程技能
查看>>
Java 集合系列-第八篇-Map架构
查看>>
springmvc 3.2 @MatrixVariable bug 2
查看>>
React-Native PanResponder手势识别器
查看>>
IOS11 光标错位问题
查看>>
如何设计用户登录
查看>>
linux安装mysql5.7.19
查看>>
Zookeeper+ActiveMQ 集群实现
查看>>
加权有向图问题2----多源最短路径问题(Floyd算法)和关键路径算法
查看>>
logback logback.xml常用配置详解(三) <filter>
查看>>
KgMall B2B/B2B2c/C2C版店铺商号初始化
查看>>
Linux内核的ioctl函数学习
查看>>
Liunx Shell入门
查看>>
Thread的中断
查看>>
linux --- 内存管理
查看>>
PostgreSQL
查看>>
CPU 超线程、多核
查看>>
用ASCII码显示string.xml中的特殊字符
查看>>