您的位置:首页 > 数据库 > Redis

redis分布式锁实现

2016-09-05 10:46 330 查看
用到的基本redis命令 setnx getset get 新手请自行脑补各个命令

实现步骤

ps:lockname 代表锁名称 time是代表 时间戳

1、setnx lockname time1

客户端c1尝试获取锁,返回1 则c1成功获取锁 可以进行操作 返回0 则表示获取锁失败 进入下一步

2、 get lockname

获取时间戳 t1 判断时间是否过期 (防止死锁)

过期? 否:结束等待下次运行 是:转3

3、 getset lockname time2

获取旧的时间 oldTime2 和第二步的时间进行比较,如果相等说明 已经成功获取了锁,如果不相等说明被别的客户端捷足先登了。进入等待状态。

源码示例:`

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;

import redis.clients.util.Pool;

public class JobUtil {

private static Logger logger = LoggerFactory.getLogger(JobUtil.class);

public static void main(String[] args) {

String str = “2016-09-01 13:16:30:125”;

Date date = null;

SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss:SSS”);//,”2016-09-01 12:36:30”);;

try {

date = sdf.parse(str);

System.out.println(” 1::: “+date.getTime());

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}
// checkWhetherCanGetLock(date.getTime()+”“,null);

}


public static boolean checkWhetherCanGetLock(String THREAD_LOCK,Jedis jedis,Integer expireSeconds){

try{

expireSeconds =expireSeconds==null ? 60*3 : expireSeconds;

long result = jedis.setnx(THREAD_LOCK, String.valueOf(new Date().getTime()));

if(result==1){ //get the lock

return true;

}else{

String timeStr = jedis.get(THREAD_LOCK);

long originTime = Long.parseLong(timeStr);

long nowTime = new Date().getTime();

if(Math.abs(nowTime-originTime)>expireSeconds*1000){//has already expire

String oldTimeStr = jedis.getSet(THREAD_LOCK, String.valueOf(new Date().getTime()));

if(StringUtils.isNotBlank(oldTimeStr)){ //check whether it is expire or not

long oldTime = Long.parseLong(oldTimeStr);

if(originTime==oldTime){

return true;

}else{

return false;

}
}else{//execute the job

return true;

}
}else{

return false;

}
}
}catch(Exception e){

e.printStackTrace();

logger.error(“判断是否获取锁失败!”);

return true;

}
}
}
`

本人这个是用于防止定时任务重复执行的,如果读者想用于处理其他的并发问题请自行封装。。。

有任何问题,欢迎直接回复或加QQ群:282034885讨论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息