展开全部
我介绍一下Redis分布式锁吧:
一、定义redis实现分布式锁的接口[java] view plain copy print?
package com.iol.common.util.concurrent.locks;
import java.io.Serializable;
/**
* Description: 定义redis实现分布式锁的算法
* This program is protected by copyright IOL_SMALL_TAIL.
* Program Name: IOL_SMALL_TAIL
* Date: 2015年11月8日
*
* @32313133353236313431303231363533e78988e69d8331333361313365author 王鑫
* @version 1.0
*/
public interface IRedisLockArithmetic extends Serializable {
/**
* 加锁算法
* @param key
* @return
*/
public boolean lock(String key);
/**
* 解锁算法
* @param key
* @return
*/
public boolean unLock(String key);
}
二、redis分布式锁基础算法实现[java] view plain copy print?
package com.iol.common.util.concurrent.locks.arithmetic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.iol.common.util.concurrent.locks.IRedisComponent;
import com.iol.common.util.concurrent.locks.IRedisLockArithmetic;
/**
* Description: redis分布式锁基础算法实现
* This program is protected by copyright IOL_SMALL_TAIL.
* Program Name: IOL_SMALL_TAIL
* Date: 2015年11月9日
*
* @author 王鑫
* @version 1.0
*/
public class RedisLockBaseArithmetic implements IRedisLockArithmetic {
/**
*serialVersionUID
*/
private static final long serialVersionUID = -8333946071502606883L;
private Logger logger = LoggerFactory.getLogger(RedisLockBaseArithmetic.class);
/**
* redis操作方法
*/
private IRedisComponent redisComp;
/**
* 超时时间,以毫秒为单位
* 默认为5分钟
*/
private long overtime = 5 * 60 * 1000L;
/**
* 休眠时长,以毫秒为单位
* 默认为100毫秒
*/
private long sleeptime = 100L;
/**
* 当前时间
*/
private long currentLockTime;
/**
* @param redisComp the redisComp to set
*/
public void setRedisComp(IRedisComponent redisComp) {
this.redisComp = redisComp;
}
/**
* @param overtime the overtime to set
*/
public void setOvertime(long overtime) {
this.overtime = overtime;
}
/**
* @param sleeptime the sleeptime to set
*/
public void setSleeptime(long sleeptime) {
this.sleeptime = sleeptime;
}
/* (non-Javadoc)
* @see com.iol.common.util.concurrent.locks.IRedisLockArithmetic#lock(java.lang.String, java.lang.Long)
*/
@Override
public boolean lock(String key) {
while(true) {
// 当前加锁时间
currentLockTime = System.currentTimeMillis();
if(redisComp.setIfAbsent(key, currentLockTime)) {
// 获取锁成功
logger.debug("直接获取锁{key: {}, currentLockTime: {}}", key, currentLockTime);
return true;
} else {
//其他线程占用了锁
logger.debug("检测到锁被占用{key: {}, currentLockTime: {}}", key, currentLockTime);
Long otherLockTime = redisComp.get(key);
if(otherLockTime == null) {
// 其他系统释放了锁
// 立刻重新尝试加锁
logger.debug("检测到锁被释放{key: {}, currentLockTime: {}}", key, currentLockTime);
continue;
} else {
if(currentLockTime - otherLockTime >= overtime) {
//锁超时
//尝试更新锁
logger.debug("检测到锁超时{key: {}, currentLockTime: {}, otherLockTime: {}}", key, currentLockTime, otherLockTime);
Long otherLockTime2 = redisComp.getAndSet(key, currentLockTime);
if(otherLockTime2 == null || otherLockTime.equals(otherLockTime2)) {
logger.debug("获取到超时锁{key: {}, currentLockTime: {}, otherLockTime: {}, otherLockTime2: {}}", key, currentLockTime, otherLockTime, otherLockTime2);
return true;
} else {
sleep();
//重新尝试加锁
logger.debug("重新尝试加锁{key: {}, currentLockTime: {}}", key, currentLockTime);
continue;
}
} else {
//锁未超时
sleep();
//重新尝试加锁
logger.debug("重新尝试加锁{key: {}, currentLockTime: {}}", key, currentLockTime);
continue;
}
}
}
}
}
/* (non-Javadoc)
* @see com.iol.common.util.concurrent.locks.IRedisLockArithmetic#unLock(java.lang.String)
*/
@Override
public boolean unLock(String key) {
logger.debug("解锁{key: {}}", key);
redisComp.delete(key);
return true;
}
/**
* 休眠
* @param sleeptime
*/
private void sleep() {
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e) {
throw new LockException("线程异常中断", e);
}
}
}