Skip to content

Instantly share code, notes, and snippets.

@suyuanhxx
Last active January 23, 2018 13:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suyuanhxx/91bc5d70a025a72f3d064bcca5fd20ea to your computer and use it in GitHub Desktop.
Save suyuanhxx/91bc5d70a025a72f3d064bcca5fd20ea to your computer and use it in GitHub Desktop.
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* Created by huangxx on 2017/6/27.
*/
@Service
@Log4j2
public class LockKeyService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
private static final String LOCK_NAME = "LOCK_NAMKE:%s";
@Override
public String getKeyByrequestId(String requestId) {
String identifier = acquireLockAndWait(requestId, 2, 5);
if (StringUtils.isNotBlank(identifier)) {
try {
secretKey = generateKey(requestId);
dosomething(secretKey);
} catch (Exception e) {
......
} finally {
releaseLock(requestId, identifier);
}
}
return secretKey;
}
/**
* @param requestId
* @param acquireLockTimeout 获取锁超时时间 单位:s
* @param lockTimeout 锁过期时间 单位:s
* @return
*/
private String acquireLockWithTimeout(String requestId, long acquireLockTimeout, long lockTimeout) {
String identifier = UUID.randomUUID().toString();
String lockName = String.format(LOCK_NAME, requestId);
long end = System.currentTimeMillis() + acquireLockTimeout * 1000;
while (System.currentTimeMillis() < end) {
if (redisTemplate.opsForValue().setIfAbsent(lockName, identifier)) {
expire(lockName, lockTimeout, TimeUnit.SECONDS);
return identifier;
}
if (redisTemplate.getExpire(lockName) == -1) {
expire(lockName, lockTimeout, TimeUnit.SECONDS);
}
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
log.error("acquireLockWithTimeout thread sleep error!", ie);
}
}
return null;
}
/**
* @param requestId
* @param waitTime 等待时间 单位:s
* @param lockTimeout 锁过期时间 单位:s
* @return
*/
private String acquireLockAndWait(String requestId, long waitTime, long lockTimeout) {
String identifier = UUID.randomUUID().toString();
String lockName = String.format(LOCK_NAME, requestId);
if (redisTemplate.opsForValue().setIfAbsent(lockName, identifier)) {
expire(lockName, lockTimeout, TimeUnit.SECONDS);
return identifier;
}
if (redisTemplate.getExpire(lockName) == -1) {
expire(lockName, lockTimeout, TimeUnit.SECONDS);
}
try {
Thread.sleep(waitTime * 1000);
} catch (InterruptedException ie) {
log.error("acquireLockAndWait thread sleep error!", ie);
}
return null;
}
/**
* 释放锁,只有锁内容符合时才会释放
*
* @param requestId 用户id
* @param identifier 锁内容
* @return
*/
private boolean releaseLock(String requestId, String identifier) {
String lockName = String.format(LOCK_NAME, requestId);
while (true) {
if (identifier.equals(redisTemplate.opsForValue().get(lockName))) {
redisTemplate.delete(lockName);
return true;
}
break;
}
return false;
}
private String dosomething(String requestId) {
......
}
private void expire(String key, long time, TimeUnit timeUnit) {
boolean success = redisTemplate.expire(key, time, timeUnit);
while(!success){
success = redisTemplate.expire(key, time, timeUnit);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment