net.lulihu.lock.ConditionLock Maven / Gradle / Ivy
package net.lulihu.lock;
import lombok.extern.slf4j.Slf4j;
import net.lulihu.ObjectKit.LogKit;
import net.lulihu.dataStructure.LRULinkedHashMap;
import net.lulihu.exception.ToolBoxException;
import java.util.Map;
import java.util.concurrent.locks.Condition;
/**
* 条件锁
*/
@Slf4j
public class ConditionLock {
// 当前的持有条件的增量
private final int incremental;
private final OrderExecuteLockKit orderExecuteLock;
private final Condition condition;
ConditionLock(int incremental, Condition condition, OrderExecuteLockKit orderExecuteLock) {
this.incremental = incremental;
this.orderExecuteLock = orderExecuteLock;
this.condition = condition;
}
/**
* 获取锁
*/
public void getLock() {
// 先行判断 是否被释放
Map.Entry currentCondition = getCurrentConditionMap();
if (currentCondition == null) return;
Integer incremental = currentCondition.getKey();
if (this.incremental < incremental)
throw new ToolBoxException("当前线程持有的条件已经被释放...");
orderExecuteLock.getLock();
boolean boo = true;
do {
currentCondition = getCurrentConditionMap();
if (currentCondition == null) return;
incremental = currentCondition.getKey();
if (!incremental.equals(this.incremental)) {
try {
condition.await();
} catch (InterruptedException e) {
if (Thread.interrupted()) {
LogKit.warn(log, "线程等待过程中被打断...");
}
}
} else boo = false;
} while (boo);
}
/**
* 使用结束释放锁
*/
public void unlock() {
Map.Entry currentCondition = getCurrentConditionMap();
if (currentCondition == null) return;
Integer incremental = currentCondition.getKey();
if (!incremental.equals(this.incremental)) {
throw new ToolBoxException("当前线程持有的条件还未获取到锁或条件已经被释放...");
}
getIncrementalSignalMap().remove(incremental);
try {
Map.Entry currentConditionMap = getCurrentConditionMap();
if (currentConditionMap != null)
currentConditionMap.getValue().signalAll();
} finally {
orderExecuteLock.unlock();
}
}
private Map.Entry getCurrentConditionMap() {
LRULinkedHashMap incrementalSignalMap = getIncrementalSignalMap();
if (incrementalSignalMap.isEmpty()) return null;
return incrementalSignalMap.getHead();
}
private LRULinkedHashMap getIncrementalSignalMap() {
return orderExecuteLock.getIncrementalSignalMap();
}
}