乐趣区

关于java:单点应用Key锁可重入锁

/**
 * 单机、粒度为 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);
    }
}
退出移动版