基于redis的分布式锁的实现
2017-02-07 10:51
519 查看
之前一直对分布式锁有所思考。一直觉得现在高性能的redis是个不错的选择;
前文:关于分布式锁的思考
今天也尝试着写了一个基于redis的分布式锁工具
LockUtil.java
给出其中连续的两次运行测试结果吧:
第一次运行(预期获得10个锁):
a7取锁结果:true
当前获取锁的数量:1
a2取锁结果:true
当前获取锁的数量:2
a1取锁结果:true
当前获取锁的数量:3
a3取锁结果:true
当前获取锁的数量:4
a9取锁结果:true
当前获取锁的数量:5
a8取锁结果:true
当前获取锁的数量:6
a0取锁结果:true
当前获取锁的数量:7
a5取锁结果:true
当前获取锁的数量:8
a6取锁结果:true
当前获取锁的数量:9
a4取锁结果:true
当前获取锁的数量:10
......................a4取锁结果:false
a7取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
..a5取锁结果:false
a6取锁结果:false
当前获取锁的数量:10
...当前获取锁的数量:10
a3取锁结果:false
a6取锁结果:false
a9取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
当前获取锁的数量:10
.a5取锁结果:false
当前获取锁的数量:10
.a8取锁结果:false
当前获取锁的数量:10
..a4取锁结果:false
a0取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
..a1取锁结果:false
a3取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
.a0取锁结果:false
当前获取锁的数量:10
.a9取锁结果:false
当前获取锁的数量:10
.a7取锁结果:false
当前获取锁的数量:10
.a2取锁结果:false
当前获取锁的数量:10
.a8取锁结果:false
当前获取锁的数量:10
..a1取锁结果:false
a2取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
接着马上运行第二次(预期就是10秒内全部不能获得锁):
...............................a6取锁结果:false
当前获取锁的数量:0
.a0取锁结果:false
当前获取锁的数量:0
.a5取锁结果:false
当前获取锁的数量:0
.a9取锁结果:false
.a3取锁结果:false
当前获取锁的数量:0
.a7取锁结果:false
当前获取锁的数量:0
.a1取锁结果:false
当前获取锁的数量:0
当前获取锁的数量:0
.a9取锁结果:false
当前获取锁的数量:0
.a8取锁结果:false
.a7取锁结果:false
当前获取锁的数量:0
.a3取锁结果:false
当前获取锁的数量:0
...当前获取锁的数量:0
.a8取锁结果:false
当前获取锁的数量:0
a4取锁结果:false
当前获取锁的数量:0
a0取锁结果:false
当前获取锁的数量:0
a2取锁结果:false
当前获取锁的数量:0
.a4取锁结果:false
当前获取锁的数量:0
...a1取锁结果:false
a9取锁结果:false
当前获取锁的数量:0
a5取锁结果:false
当前获取锁的数量:0
当前获取锁的数量:0
....a2取锁结果:false
.a0取锁结果:false
当前获取锁的数量:0
a1取锁结果:false
a7取锁结果:false
.a4取锁结果:false
当前获取锁的数量:0
a2取锁结果:false
当前获取锁的数量:0
..a8取锁结果:false
.当前获取锁的数量:0
当前获取锁的数量:0
a6取锁结果:false
当前获取锁的数量:0
.a5取锁结果:false
a3取锁结果:false
当前获取锁的数量:0
当前获取锁的数量:0
当前获取锁的数量:0
当前获取锁的数量:0
.a6取锁结果:false
当前获取锁的数量:0
效果还是很理想的。有待实践吧。
前文:关于分布式锁的思考
今天也尝试着写了一个基于redis的分布式锁工具
LockUtil.java
package yyf.Jedis.toolsByRedis; import java.util.concurrent.atomic.AtomicInteger; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * 基于redis的分布式锁工具 * * @author yuyufeng * */ public class LockUtil { // 获取redis static JedisPool jedisPool; static { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(100); config.setMaxIdle(5); config.setMaxWaitMillis(1000); config.setTestOnBorrow(false); // 构造池 jedisPool = new JedisPool(config, "127.0.0.1", 6379, 1000, "12345"); } // redis键值前缀标识 private final static String PREFIX = "LOCK-FLAG-"; // 默认获取锁的等待时间 private final static Integer WAITTIME = 200; /** * 获取锁 * * @param uid:锁的唯一标识 * @param expire:锁自动释放时间 * @return true:获得锁;false:锁已被占用 */ public static Boolean getLock(String uid, Integer expire) { if (expire < 0) { return false; } Long beginTime = System.currentTimeMillis(); do { Jedis jedis = jedisPool.getResource(); //防止程序出错设置键值不失效 if(jedis.ttl(PREFIX + uid) == -1){ jedis.expire(PREFIX + uid, expire); } Long res = jedis.incr(PREFIX + uid); if (res == 1) { jedis.expire(PREFIX + uid, expire); if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } return true; } if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("."); } while ((System.currentTimeMillis() - beginTime) < WAITTIME); return false; } /** * 获取锁 * * @param uid:锁的唯一标识 * @param expire:锁自动释放时间 * @param timeout:超时等待时间 * @return true:获得锁;false:锁已被占用 */ public static Boolean getLock(String uid, Integer expire, Integer timeout) { if (expire < 0) { return false; } Long beginTime = System.currentTimeMillis(); do { Jedis jedis = jedisPool.getResource(); //防止程序出错设置键值不失效 if(jedis.ttl(PREFIX + uid) == -1){ jedis.expire(PREFIX + uid, expire); } Long res = jedis.incr(PREFIX + uid); if (res == 1) { jedis.expire(PREFIX + uid, expire); if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } return true; } if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("."); } while ((System.currentTimeMillis() - beginTime) < timeout); return false; } /** * 手动释放锁 * * @param uid:锁的唯一标识 */ public static void returnLock(String uid) { Jedis jedis = jedisPool.getResource(); jedis.del(PREFIX + uid); if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } System.out.println("手动释放锁:" + uid); } /** * 测试 * * @param args */ public static void main(String[] args) { AtomicInteger ai = new AtomicInteger(1); AtomicInteger count = new AtomicInteger(0); for (int i = 0; i < 30; i++) { new Thread() { @Override public void run() { String uid = "a" + ai.incrementAndGet() % 10; // 获取锁,并设置10秒失效 Boolean lock = LockUtil.getLock(uid, 10); System.out.println(uid + "取锁结果:" + lock); if (lock) { // dosomething.. count.incrementAndGet(); } System.out.println("当前获取锁的数量:"+count); } }.start(); } // 手动解锁测试,超时测试 //Boolean lock = LockUtil.getLock("testReturnKey", 1); //System.out.println("testReturnKey" + "取锁结果:" + lock); // LockUtil.returnLock("testReturnKey"); } }
给出其中连续的两次运行测试结果吧:
第一次运行(预期获得10个锁):
a7取锁结果:true
当前获取锁的数量:1
a2取锁结果:true
当前获取锁的数量:2
a1取锁结果:true
当前获取锁的数量:3
a3取锁结果:true
当前获取锁的数量:4
a9取锁结果:true
当前获取锁的数量:5
a8取锁结果:true
当前获取锁的数量:6
a0取锁结果:true
当前获取锁的数量:7
a5取锁结果:true
当前获取锁的数量:8
a6取锁结果:true
当前获取锁的数量:9
a4取锁结果:true
当前获取锁的数量:10
......................a4取锁结果:false
a7取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
..a5取锁结果:false
a6取锁结果:false
当前获取锁的数量:10
...当前获取锁的数量:10
a3取锁结果:false
a6取锁结果:false
a9取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
当前获取锁的数量:10
.a5取锁结果:false
当前获取锁的数量:10
.a8取锁结果:false
当前获取锁的数量:10
..a4取锁结果:false
a0取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
..a1取锁结果:false
a3取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
.a0取锁结果:false
当前获取锁的数量:10
.a9取锁结果:false
当前获取锁的数量:10
.a7取锁结果:false
当前获取锁的数量:10
.a2取锁结果:false
当前获取锁的数量:10
.a8取锁结果:false
当前获取锁的数量:10
..a1取锁结果:false
a2取锁结果:false
当前获取锁的数量:10
当前获取锁的数量:10
接着马上运行第二次(预期就是10秒内全部不能获得锁):
...............................a6取锁结果:false
当前获取锁的数量:0
.a0取锁结果:false
当前获取锁的数量:0
.a5取锁结果:false
当前获取锁的数量:0
.a9取锁结果:false
.a3取锁结果:false
当前获取锁的数量:0
.a7取锁结果:false
当前获取锁的数量:0
.a1取锁结果:false
当前获取锁的数量:0
当前获取锁的数量:0
.a9取锁结果:false
当前获取锁的数量:0
.a8取锁结果:false
.a7取锁结果:false
当前获取锁的数量:0
.a3取锁结果:false
当前获取锁的数量:0
...当前获取锁的数量:0
.a8取锁结果:false
当前获取锁的数量:0
a4取锁结果:false
当前获取锁的数量:0
a0取锁结果:false
当前获取锁的数量:0
a2取锁结果:false
当前获取锁的数量:0
.a4取锁结果:false
当前获取锁的数量:0
...a1取锁结果:false
a9取锁结果:false
当前获取锁的数量:0
a5取锁结果:false
当前获取锁的数量:0
当前获取锁的数量:0
....a2取锁结果:false
.a0取锁结果:false
当前获取锁的数量:0
a1取锁结果:false
a7取锁结果:false
.a4取锁结果:false
当前获取锁的数量:0
a2取锁结果:false
当前获取锁的数量:0
..a8取锁结果:false
.当前获取锁的数量:0
当前获取锁的数量:0
a6取锁结果:false
当前获取锁的数量:0
.a5取锁结果:false
a3取锁结果:false
当前获取锁的数量:0
当前获取锁的数量:0
当前获取锁的数量:0
当前获取锁的数量:0
.a6取锁结果:false
当前获取锁的数量:0
效果还是很理想的。有待实践吧。
相关文章推荐
- 基于Redis实现分布式消息队列(1)
- 基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有测试代码(何志雄)
- 基于Redis实现分布式锁-Redisson使用及源码分析
- 基于Redis实现分布式锁
- 基于Redis实现简单的分布式锁
- 基于Redis实现分布式消息队列(2)
- 基于Python,scrapy,redis的分布式爬虫实现框架
- 基于Redis实现分布式锁
- 基于Redis实现分布式锁以及任务队列
- 基于Redis实现分布式锁
- 基于Redis实现分布式消息队列(4)
- [转载] 基于Redis实现分布式消息队列
- 基于Redis实现分布式锁
- 基于Redis实现分布式锁,Redisson使用及源码分析
- 缓存篇~第七回 Redis实现基于方法签名的数据集缓存(可控更新,分布式数据缓存)
- 基于Redis实现分布式消息队列(汇总目录)
- 基于Redis Lua脚本实现的分布式锁 | 日拱一卒
- 基于Python,scrapy,redis的分布式爬虫实现框架
- 基于Redis实现分布式锁
- 基于Redis实现分布式锁,Redisson使用及源码分析