Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jizcode.lock.LockManager Maven / Gradle / Ivy
package jizcode.lock;
import jizcode.base.Jizcode;
import jizcode.base.tool.CacheTool;
import jizcode.base.util.ConvertUtil;
import jizcode.base.util.DateUtil;
import jizcode.base.util.StringUtils;
import java.util.Date;
import java.util.Map;
class LockManager {
private static Object LockObj = new Object();
public static boolean addKey(CacheTool cache, String key, int timeout) {
if (timeout <= 0) {
return false;
}
try {
Date nowForCheck = new Date();
String actualKey = String.format(CacheTool.PrefixForLockPrimay, key);
if (!canLock(cache, key, nowForCheck)) {
return false;
}
synchronized (LockObj) {
if (!canLock(cache, key, nowForCheck)) {
return false;
}
String timeString = String.format("%s;%s", timeout, DateUtil.toDateTimeString(DateUtil.addSeconds(new Date(), timeout)));
cache.set(actualKey, timeString);
return true;
}
} catch (Exception e) {
return false;
}
}
public static void removeKey(CacheTool cache, String key) {
String actualKey = String.format(CacheTool.PrefixForLockPrimay, key);
try {
synchronized (LockObj) {
cache.remove(actualKey);
}
} catch (Exception e) {
}
}
public static boolean addKeys(CacheTool cache, String[] keys, int timeout) {
if (timeout <= 0) {
return false;
}
try {
Date nowForCheck = new Date();
if (!canLock(cache, keys, nowForCheck)) {
return false;
}
synchronized (LockObj) {
if (!canLock(cache, keys, nowForCheck)) {
return false;
}
String keyValue = String.format("%s;%s", timeout, DateUtil.toDateTimeString(DateUtil.addSeconds(new Date(), timeout)));
for (int index = 0; index < keys.length; index++) {
String actualKey = String.format(CacheTool.PrefixForLockPrimay, keys[index]);
cache.set(actualKey, keyValue);
}
return true;
}
} catch (Exception e) {
Jizcode.getLog().error("add keys error", e);
return false;
}
}
public static void removeKeys(CacheTool cache, String[] keys) {
try {
synchronized (LockObj) {
for (int index = 0; index < keys.length; index++) {
String actualKey = String.format(CacheTool.PrefixForLockPrimay, keys[index]);
cache.tryRemove(actualKey);
}
}
} catch (Exception e) {
}
}
/**
* 添加注册关联key
* @param cache
* @param primaryKey
* @param relativekey
* @param timeout
*/
public static boolean addKey(CacheTool cache, String primaryKey, String relativekey, int timeout) {
if (timeout <= 0) {
return false;
}
try {
Date nowForCheck = new Date();
String actualPrimaryKey = String.format(CacheTool.PrefixForLockPrimay, primaryKey);
String actualRelativeKey = String.format(CacheTool.PrefixForLockRelative, relativekey);
if(!canLock(cache, primaryKey, nowForCheck)) {
return false;
}
synchronized (LockObj) {
if (!canLock(cache, primaryKey, nowForCheck)) {
return false;
}
String timeString = String.format("%s;%s", timeout, DateUtil.toDateTimeString(DateUtil.addSeconds(new Date(), timeout)));
// l0:primaryKey timeout;time;relativeKey
cache.set(actualPrimaryKey, String.format("%s;%s", timeString, relativekey));
Jizcode.getLog().debug("add lock:{} time:{} timeout:{}", primaryKey, timeString, timeout);
// l1:relativeKey l1:c 0
// primaryKey time
// primaryKey time
int count = ConvertUtil.tryToInteger(cache.mapGet(actualRelativeKey, CacheTool.LockRelativeCountKey), 0);
String relativeTimeString = cache.mapGet(actualRelativeKey, primaryKey);
if(StringUtils.isNullOrEmpty((relativeTimeString))) {
count++;
}
cache.mapAdd(actualRelativeKey, CacheTool.LockRelativeCountKey, String.valueOf(count));
cache.mapAdd(actualRelativeKey, primaryKey, timeString);
Jizcode.getLog().debug("add relative lock:{} for:{} count:{}", primaryKey, relativekey, count);
return true;
}
} catch (Exception e) {
Jizcode.getLog().error("addKey error", e);
return false;
}
}
public static void removeKey(CacheTool cache, String primaryKey, String relativekey) {
String actualPrimaryKey = String.format(CacheTool.PrefixForLockPrimay, primaryKey);
String actualRelativeKey = String.format(CacheTool.PrefixForLockRelative, relativekey);
synchronized (LockObj) {
cache.tryRemove(actualPrimaryKey);
int count = ConvertUtil.tryToInteger(cache.mapGet(actualRelativeKey, CacheTool.LockRelativeCountKey), 0);
String relativeTimeString = cache.mapGet(actualRelativeKey, primaryKey);
if(!StringUtils.isNullOrEmpty((relativeTimeString))) {
count--;
}
cache.tryMapAdd(actualRelativeKey, CacheTool.LockRelativeCountKey, String.valueOf(count));
cache.tryMapRemove(actualRelativeKey, primaryKey);
Jizcode.getLog().debug("remove relative lock:{} for:{}", primaryKey, relativekey);
}
}
public static boolean addKeys(CacheTool cache, String[] primaryKeys, String relativeKey, int timeout) {
if (timeout <= 0) {
return false;
}
try {
Date nowForCheck = new Date();
if (!canLock(cache, primaryKeys, nowForCheck)) {
return false;
}
synchronized (LockObj) {
if (!canLock(cache, primaryKeys, nowForCheck)) {
return false;
}
String timeString = String.format("%s;%s", timeout, DateUtil.toDateTimeString(DateUtil.addSeconds(new Date(), timeout)));
for(int index = 0; index < primaryKeys.length; index++) {
String primaryKey = primaryKeys[index];
String actualPrimaryKey = String.format(CacheTool.PrefixForLockPrimay, primaryKey);
String actualRelativeKey = String.format(CacheTool.PrefixForLockRelative, relativeKey);
// l0:primaryKey timeout;time;relativeKey
cache.set(actualPrimaryKey, String.format("%s;%s", timeString, relativeKey));
Jizcode.getLog().debug("add lock:{} time:{} timeout:{}", primaryKey, timeString, timeout);
// l1:relativeKey l1:c 0
// primaryKey time
// primaryKey time
int count = ConvertUtil.tryToInteger(cache.mapGet(actualRelativeKey, CacheTool.LockRelativeCountKey), 0);
String relativeTimeString = cache.mapGet(actualRelativeKey, primaryKey);
if (StringUtils.isNullOrEmpty((relativeTimeString))) {
count++;
}
cache.mapAdd(actualRelativeKey, CacheTool.LockRelativeCountKey, String.valueOf(count));
cache.mapAdd(actualRelativeKey, primaryKey, timeString);
Jizcode.getLog().debug("add relative lock:{} for:{} count:{}", primaryKey, relativeKey, count);
}
return true;
}
} catch (Exception e) {
Jizcode.getLog().error("add keys error", e);
return false;
}
}
public static void removeKeys(CacheTool cache, String[] primaryKeys, String relativeKey) {
try {
synchronized (LockObj) {
for (int index = 0; index < primaryKeys.length; index++) {
String primaryKey = primaryKeys[index];
String actualPrimaryKey = String.format(CacheTool.PrefixForLockPrimay, primaryKey);
String actualRelativeKey = String.format(CacheTool.PrefixForLockRelative, relativeKey);
cache.tryRemove(actualPrimaryKey);
int count = ConvertUtil.tryToInteger(cache.mapGet(actualRelativeKey, CacheTool.LockRelativeCountKey), 0);
String relativeTimeString = cache.mapGet(actualRelativeKey, primaryKey);
if(!StringUtils.isNullOrEmpty((relativeTimeString))) {
count--;
}
cache.tryMapAdd(actualRelativeKey, CacheTool.LockRelativeCountKey, String.valueOf(count));
cache.tryMapRemove(actualRelativeKey, primaryKey);
Jizcode.getLog().debug("remove relative lock:{} for:{}", primaryKey, relativeKey);
}
}
} catch (Exception e) {
}
}
//#region private method
private static boolean canLock(CacheTool cache,
String primaryKey,
Date nowForCheck) {
String actualPrimaryKey = String.format(CacheTool.PrefixForLockPrimay, primaryKey);
String actualRelativeKey = String.format(CacheTool.PrefixForLockRelative, primaryKey);
boolean canLock = true;
// 检查自己有没有被锁
String primaryLockValue = cache.tryGet(actualPrimaryKey, null);
if (!StringUtils.isNullOrEmpty(primaryLockValue)) {
String[] value = primaryLockValue.split(";");
int timeoutFromCache = ConvertUtil.tryToInteger(value[0], 0);
Date timeFromCache = ConvertUtil.tryToDate(value[1], DateUtil.MinDate);
if (DateUtil.getDiffSeconds(nowForCheck, timeFromCache) < timeoutFromCache) {
Jizcode.getLog().debug("{} has lock time:{}, timeout:{}", primaryKey, value[1], timeoutFromCache);
canLock = false;
}
}
if (!canLock) {
return canLock;
}
// 检查是否有被别人锁
int relativeLockCount = ConvertUtil.tryToInteger(cache.tryMapGet(actualRelativeKey, CacheTool.LockRelativeCountKey), 0);
if (relativeLockCount > 0){
Map relativeMap = cache.tryMap(actualRelativeKey);
if(relativeMap != null) {
for(Map.Entry entry : relativeMap.entrySet()) {
String[] value = entry.getValue().split(";");
int timeoutFromCache = ConvertUtil.tryToInteger(value[0], 0);
Date timeFromCache = ConvertUtil.tryToDate(value[1], DateUtil.MinDate);
if(DateUtil.getDiffSeconds(nowForCheck, timeFromCache) <= timeoutFromCache){
Jizcode.getLog().debug("{} has relative lock {}, time:{}, timeout:{}", primaryKey, entry.getKey(), value[1], timeoutFromCache);
canLock = false;
break;
}
}
}
}
return canLock;
}
private static boolean canLock(CacheTool cache,
String[] primaryKeys,
Date nowForCheck) {
for(int index = 0; index < primaryKeys.length; index++) {
if(!canLock(cache, primaryKeys[index], nowForCheck)){
return false;
}
}
return true;
}
//endregion
}