/**
* 单机、粒度为key的可重入锁。
* 同一个 key、同一时刻,只能一个线程执行
* @see java.util.concurrent.locks.Lock
* @see java.util.concurrent.locks.ReentrantLock
*/
public interface KeyLock<T> {
/**
* 加锁
*/
void lock(T key);
boolean tryLock(T key, long time, TimeUnit unit);
/**
* 解锁
*/
void unlock(T key);
}
@Slf4j
public class DefaultKeyLock<T> implements KeyLock<T> {
private final Map<T, ReentrantLock> lockMap = new ConcurrentHashMap<>();
@Override
public void lock(T key) {
Preconditions.checkArgument(Objects.nonNull(key), "key can not be null ");
ReentrantLock lock = lockMap.computeIfAbsent(key, k -> new ReentrantLock());
lock.lock();
}
@SneakyThrows(value = {InterruptedException.class})
@Override
public boolean tryLock(T key, long time, TimeUnit unit) {
Preconditions.checkArgument(Objects.nonNull(key), "key can not be null ");
ReentrantLock lock = lockMap.computeIfAbsent(key, k -> new ReentrantLock());
boolean flag = lock.tryLock(time, unit);
if (flag) {
log.info("get the lock {} success", key);
} else {
log.info("get the lock {} failure", key);
}
return flag;
}
@Override
public void unlock(T key) {
Preconditions.checkArgument(Objects.nonNull(key), "key can not be null ");
ReentrantLock lock = lockMap.get(key);
if (Objects.isNull(lock)) {
throw new IllegalArgumentException("key: " + key + " does not own a lock ");
}
if (!lock.isHeldByCurrentThread()) {
throw new IllegalStateException("current thread does not oww a lock,key:" + key);
}
lock.unlock();
log.info("release the lock {} success", key);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。