博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jedis分布式锁实现
阅读量:5937 次
发布时间:2019-06-19

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

 redis分布式锁解决多个应用进程间同步操作

整理了很多网上文档 发现都没有解决如下问题。。。

参考

http://www.cnblogs.com/it-cen/p/4984272.html

...

1.时间同步问题

2.在一个进程cash后失效时间后自动释放锁

3.有些多线程race condition没有考虑到

 

以下java版本实现彻底解决  充分测试   

 

import java.util.List;import java.util.UUID;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.Transaction;import redis.clients.jedis.exceptions.JedisException;/** * Jedis实现分布式锁 *  * @author 三文鱼 * */public class DistributionLock {    private final JedisPool jedisPool;    public DistributionLock(JedisPool jedisPool) {        this.jedisPool = jedisPool;    }    /**     * 获取分布式锁     *      * @param lockName     *            竞争获取锁key     * @param acquireTimeoutInMS     *            获取锁超时时间     * @param lockTimeoutInMS     *            锁的超时时间     * @return 获取锁标识     */    public String acquireLockWithTimeout(String lockName,            long acquireTimeoutInMS, long lockTimeoutInMS) {        Jedis conn = null;        boolean broken = false;        String retIdentifier = null;        try {            conn = jedisPool.getResource();            String identifier = UUID.randomUUID().toString();            String lockKey = "lock:" + lockName;            int lockExpire = (int) (lockTimeoutInMS / 1000);            long end = System.currentTimeMillis() + acquireTimeoutInMS;            while (System.currentTimeMillis() < end) {                if (conn.setnx(lockKey, identifier) == 1) {                    conn.expire(lockKey, lockExpire);                    retIdentifier = identifier;                }                if (conn.ttl(lockKey) == -1) {                    conn.expire(lockKey, lockExpire);                }                try {                    Thread.sleep(10);                } catch (InterruptedException ie) {                    Thread.currentThread().interrupt();                }            }        } catch (JedisException je) {            if (conn != null) {                broken = true;                jedisPool.returnBrokenResource(conn);            }        } finally {            if (conn != null && !broken) {                jedisPool.returnResource(conn);            }        }        return retIdentifier;    }    /**     * 释放锁     * @param lockName 竞争获取锁key     * @param identifier 释放锁标识     * @return     */    public boolean releaseLock(String lockName, String identifier) {        Jedis conn = null;        boolean broken = false;        String lockKey = "lock:" + lockName;        boolean retFlag = false;        try {            conn = jedisPool.getResource();            while (true) {                conn.watch(lockKey);                if (identifier.equals(conn.get(lockKey))) {                    Transaction trans = conn.multi();                    trans.del(lockKey);                    List results = trans.exec();                    if (results == null) {                        continue;                    }                    retFlag = true;                }                conn.unwatch();                break;            }        } catch (JedisException je) {            if (conn != null) {                broken = true;                jedisPool.returnBrokenResource(conn);            }        } finally {            if (conn != null && !broken) {                jedisPool.returnResource(conn);            }        }        return retFlag;    }}

 

转载于:https://www.cnblogs.com/wuhuajun/p/5242644.html

你可能感兴趣的文章
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>
洛谷 P2486 BZOJ 2243 [SDOI2011]染色
查看>>
linux 笔记本的温度提示
查看>>
数值积分中的辛普森方法及其误差估计
查看>>
Web service (一) 原理和项目开发实战
查看>>
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
广平县北方计算机第一届PS设计大赛
查看>>
深入理解Java的接口和抽象类
查看>>
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>
基于事件驱动的DDD领域驱动设计框架分享(附源代码)
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>
JFreeChart开发_用JFreeChart增强JSP报表的用户体验
查看>>
度量时间差
查看>>