/** * 单机、粒度为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);}
@Slf4jpublic 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); }}