redis的分布式锁工具LockUtil
/**
* 基于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"); }
redis的分布式锁工具LockUtil的更多相关文章
- java中redis的分布式锁工具类
		
使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...
 - redis实现分布式锁工具类 灰常好用
		
public interface RedisDistributionLock { /** * 加锁成功,返回加锁时间 * @param lockKey * @param threadName * @r ...
 - redis实现分布式锁--工具类
		
1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
 - 基于redis的分布式锁实现
		
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
 - 基于redis的分布式锁的分析与实践
		
 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...
 - 基于redis的分布式锁二种应用场景
		
“分布式锁”是用来解决分布式应用中“并发冲突”的一种常用手段,实现方式一般有基于zookeeper及基于redis二种.具体到业务场景中,我们要考虑二种情况: 一.抢不到锁的请求,允许丢弃(即:忽略) ...
 - Redis的分布式锁
		
一.锁的作用 当多线程执行某一业务时(特别是对数据的更新.新增)等操作,可能就会出现多个线程对同一条数据进行修改.其最终的结果一定与你期望的结果“不太一样”,这就与需要一把锁来控制线程排排队了 - j ...
 - 基于redis的分布式锁实现方案--redisson
		
实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill redis官方文档地址,请前往:http://www.redis.cn/topi ...
 - Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流
		
1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...
 
随机推荐
- linux环境下protobuf安装
			
1. 到GitHub下载源码,执行解压命令后,进入解压后的目录 2. 执行./autogen,生成configure 3. 执行./configure --prefix=/usr/local/,pro ...
 - Linux入门到放弃之二《目录处理常用命令的使用方法》
			
一,目录操作命令 1.用pwd命令查看当前所在的目录: 2.用ls命令列出此目录下的文件和目录: 3.列出此目录下包括隐藏文件在内的所有文件和目录并且长格式显示: ( -l表示长格式,-a表示隐藏文 ...
 - 解谜:为何用了9-Patch背景图后自带Padding属性?
			
本次分享的主题源于笔者在实际开发中遇到的问题. 具体现象为:当普通的9-Patch图用作TextView的backGround属性后,整个TextView便有了一定的Padding值.但笔者并没有给定 ...
 - C# 编译器对局部变量的优化
			
C# 编译器对局部变量的优化 C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题. 不考虑基本的对齐和换行美化.看一下局部变量优化问题. C# 示例代码 例 ...
 - PHP中双引号和单引号的区别
			
在PHP中,字符串数值有单引号和双引号两种. 区别: 单引号:系统不做复杂的转义.只转义\'和\\两种转义,其他的按原样输出. 双引号:则转义比较多,\",\\,\r,\t,\n,\$等. ...
 - layer弹窗动态改变标题
			
1.利用layer弹出iframe层(type=2) 1 function ShowKJCX(results) { 2 ly = layer.open({ 3 type: 2, 4 id:" ...
 - Luogu P1625 求和
			
题意 给定两个整数 \(n,m\),求 \[\sum\limits_{i=1}^{n}\frac{1}{\prod\limits_{j=i}^{i+m-1}j} \] \(\texttt{Data R ...
 - JavaScript之构造函数
			
在学习构造函数之前我们需要知道我们学习构造函数需要学习什么: 1.什么是构造函数 2.构造函数用来做什么 3.构造函数的执行过程 4.构造函数的返回值 1.所以首先我们需要知道什么是构造函数: 在 ...
 - leetcode73:minmum-window-substring
			
题目描述 给出两个字符串S和T,要求在O(n)的时间复杂度内在S中找出最短的包含T中所有字符的子串. 例如: S ="ADOBECODEBANC" T ="ABC&quo ...
 - 80386学习(一) 80386CPU介绍
			
一.80386CPU介绍 Inter80386CPU是Inter公司于1985年推出的第一款32位80x86系列的微处理器.80386的数据总线是32位的,其地址总线也是32位,因而最大可寻址4GB的 ...