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

NewBie
10 声望0 粉丝