/**
* @param lockName 锁名称/路径
* @param waitTime 锁获取等待时间 秒 传空默认10秒
* @param lockTime 最长加锁时间 秒 传空默认5*60秒
* @return
* @describe: 获取一个锁,如果是没有加锁,则会直接获得,如果加锁,会根据等待时间获取锁
* @author: jiahong.xing/
* @version: v1.0
* @date 2018/8/21/021 15:13
*/
public static boolean getLock(String lockName, Integer waitTime, Integer lockTime) {
if (StringUtils.isEmpty(lockName)) {
return false;
}
if (null == waitTime) {
waitTime = maxWaitTime;
}
if (null == lockTime) {
lockTime = maxLockTime;
}
Long wTime = System.currentTimeMillis() + (waitTime * 1000);
try {
while (true) {
Long inTime = System.currentTimeMillis();
//如果当前时间大于设置值,则跳出等待
if (inTime >= wTime) {
return false;
}
boolean isok = RedisUtil.redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
return connection.setNX(lockName.getBytes(), lockName.getBytes());
}
});
if (isok) {
//所有加锁成功的,均在线程数据里面增加一条,可以在清理线程数据的时候进行解锁,同时也可以手动解锁
synchronized (Thread.currentThread()) {
SessionRdsLockData.add(lockName);
}
RedisUtil.redisTemplate.expire(lockName, lockTime, TimeUnit.SECONDS);
return true;
}
//设置等待时间,不无限请求redis
Thread.sleep(200);
}
} catch (Exception e) {
e.printStackTrace();
//获取锁失败
log.error("获取锁失败:{}", lockName);
return false;
}
}
//解锁
public static void unLock(String lockName) {
if (StringUtils.isEmpty(lockName)) {
return;
}
RedisUtil.remove(lockName);
SessionRdsLockData.remove(lockName);
}
// 删除对应的value
public static void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
假如A线程获取到锁的线程在指定时间内没有完成,key就会被删除,那么B线程就可以获取到锁,那么A执行unLock方法删除的不就是B线程的key了么,那么多线程情况下就会出现锁不住的情况了把?