redis锁
Posted zfzf1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis锁相关的知识,希望对你有一定的参考价值。
拓展 ycgwl-cache RedisStorage
/** * 如果不存在则 写入缓存并设置过期时间 * @param key * @param value * @param expire * @return */ public synchronized Long setnx(String key, V value,int expire) { Jedis j = null; String svalue = JsonUtils.toJsonString(value); boolean borrowOrOprSuccess = true; try { j = this.client.getResource(); Long setnx = j.setnx(key, svalue); j.expire(key, expire); return setnx; } catch (JedisException var10) { borrowOrOprSuccess = false; if (j != null) { this.client.returnBrokenResource(j); } LOG.error(var10.getMessage(), "EXCEPTION", var10); } finally { if (borrowOrOprSuccess) { this.client.returnResource(j); } } return 0L; }
框架 redis包 添加 RedisLock
package lock.lock;
import com.ycgwl.cache.storage.RedisStorage;
import java.util.Random;
public class RedisLock {
//纳秒和毫秒之间的转换率
public static final long MILLI_NANO_TIME = 1000 * 1000L;
//表示被锁定的 value 值
public static final String LOCKED = "TRUE";
public static final Random RANDOM = new Random();
//reids key
private String key;
//封装的操作redis的工具
private RedisStorage storage;
//是否锁定成功
private boolean lock = true;
//尝试获取锁的时间上限 毫秒
public static Long TRY_LOCK_TIME_OUT_MILLI_SECOND=2000l;
//自动失效时间 秒
public static int EXPIRE_SECOND=100;
/**
*
* @param purpose key的前缀
* @param key 一般都是数据的id
* @param storage redis客户端
*/
public RedisLock(String purpose, String key, RedisStorage storage){
this.key = purpose + "_" + key + "_lock";
this.storage = storage;
}
/**
* 默认 轮询尝试2秒 100秒失效
* @return
*/
public boolean lock(){
return this.lock(TRY_LOCK_TIME_OUT_MILLI_SECOND,EXPIRE_SECOND);
}
/**
* 加锁
* 使用方式为:
* lock();
* try{
* executeMethod();
* }finally{
* unlock();
* }
* @param timeout timeout的时间范围内轮询锁 纳秒
* @param expire 设置锁超时时间 秒
* @return 成功 or 失败
*/
public boolean lock(long timeout,int expire){
//获取当前纳秒级时间
long nanoTime = System.nanoTime();
//超时时间转纳秒
timeout *= MILLI_NANO_TIME;
try {
//在timeout的时间范围内不断尝试写入锁
while (System.nanoTime() - nanoTime < timeout) {
//锁不存在的话,设置锁并设置锁过期时间,即加锁
if (this.storage.setnx(this.key, LOCKED,expire) == 1) {
//设置锁过期时间是为了在没有释放锁的情况下锁过期后消失,不会造成永久阻塞
this.lock = true;
return this.lock;
}
//短暂休眠,避免可能的活锁
Thread.sleep(3, RANDOM.nextInt(30));
}
} catch (Exception e) {
throw new RuntimeException("获取锁失败",e);
}
return false;
}
/**
* 解锁
*/
public void unlock() {
try {
if(this.lock){
storage.remove(key);//直接删除
}
} catch (Throwable e) {
throw new RuntimeException("删除锁失败",e);
}
}
}
新添加加锁接口
@Resource private RedisStorage storage; @Override public void updateOrderByLock(Long id){ RedisLock redisLock = new RedisLock("BaseSiteEntity_SiteId", id + "", this.storage); boolean result = redisLock.lock(); //取锁失败 if(!result){ throw new RuntimeException("id:"+id+" 获取锁失败"); } try{ //执行方法 updateOrderBy(id); }finally{ //释放锁 redisLock.unlock(); } }
其他 http://www.cnblogs.com/zfzf1/p/7768211.html
以上是关于redis锁的主要内容,如果未能解决你的问题,请参考以下文章