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