All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.netkit.redis.client.executor.RedisLockClient Maven / Gradle / Ivy

The newest version!
package top.netkit.redis.client.executor;

import org.redisson.RedissonMultiLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * redis lock client
 *
 * @author shixinke
 */
public class RedisLockClient implements RedisLockExecutor {


    private RedissonClient redissonClient;

    private static final Logger logger = LoggerFactory.getLogger(RedisCommandClient.class);

    public RedisLockClient() {
    }

    public RedisLockClient(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Override
    public  T lock(String key, int timeout, TimeUnit timeUnit, ReturnableExecutor executor) {
        return lock(key, false, timeout, timeUnit, executor);
    }


    @Override
    public void lock(String key, int timeout, VoidExecutor executor) {
        lock(key, false, timeout, TimeUnit.MILLISECONDS, executor);
    }

    @Override
    public  T tryLock(String key, int waitTime, int releaseTime, TimeUnit timeUnit, ReturnableExecutor executor) {
        RLock lock = redissonClient.getLock(key);
        try {
            boolean result = lock.tryLock(waitTime, releaseTime, timeUnit);
            if (!result) {
                throw new RedisLockException();
            }
            return executor.execute(null);
        } catch (InterruptedException ex) {
            throw new RedisLockException(ex);
        } finally {
            releaseLock(lock);
        }
    }

    @Override
    public void tryLock(String key, int waitTime, int releaseTime, TimeUnit timeUnit, VoidExecutor executor) {
        RLock lock = redissonClient.getLock(key);
        try {
            boolean result = lock.tryLock(waitTime, releaseTime, timeUnit);
            if (!result) {
                throw new RedisLockException();
            }
            executor.execute();
        } catch (InterruptedException ex) {
            throw new RedisLockException(ex);
        } finally {
            releaseLock(lock);
        }
    }

    @Override
    public  T tryLock(String key, int waitTime, int releaseTime, ReturnableExecutor executor) {
        return tryLock(key, waitTime, releaseTime, TimeUnit.MILLISECONDS, executor);
    }

    @Override
    public void tryLock(String key, int waitTime, int releaseTime, VoidExecutor executor) {
        tryLock(key, waitTime, releaseTime, TimeUnit.MILLISECONDS, executor);
    }


    /**
     * todo
     * @param key lock key
     * @param readTimeout read lock timeout
     * @param writeTimeout write lock timeout
     * @param readExecutor business executor when get read lock
     * @param writeExecutor business executor when get write lock
     * @return T
     */
    @Override
    public  T readWriteLock(String key, int readTimeout, int writeTimeout, ReturnableExecutor readExecutor, ReturnableExecutor writeExecutor) {
        ReadWriteLock readWriteLock = redissonClient.getReadWriteLock(key);
        Lock readLock = readWriteLock.readLock();
        boolean locked = false;
        try {
            locked = readLock.tryLock(readTimeout, TimeUnit.MILLISECONDS);
        } catch (Exception ex) {
            throw new RedisLockException(ex);
        }

        if (!locked) {
            throw new RedisLockException();
        }
        R readResult = null;
        try {
            readResult = readExecutor.execute(null);
        } finally {
            if (writeExecutor == null) {
                readLock.unlock();
            }
        }
        if (writeExecutor == null) {
            return null;
        }

        Lock writeLock = readWriteLock.writeLock();
        locked = false;
        try {
            locked = writeLock.tryLock(writeTimeout, TimeUnit.MILLISECONDS);
        } catch (Exception ex) {
            readLock.unlock();
            throw new RedisLockException(ex);
        }

        if (!locked) {
            readLock.unlock();
            throw new RedisLockException();
        }
        try {
            return writeExecutor.execute(readResult);
        } finally {
            writeLock.unlock();
            readLock.unlock();
        }
    }

    @Override
    public void lock(String key, int timeout, TimeUnit timeUnit, VoidExecutor executor) {
        lock(key, false, timeout, timeUnit, executor);
    }

    @Override
    public  T lock(String key, int timeout, ReturnableExecutor executor) {
        return lock(key, false, timeout, TimeUnit.MILLISECONDS, executor);
    }

    @Override
    public  T lock(String key, boolean fair, int timeout, TimeUnit timeUnit, ReturnableExecutor executor) {
        RLock lock = null;
        if (fair) {
            lock = redissonClient.getFairLock(key);
        } else {
            lock = redissonClient.getLock(key);
        }
        try {
            lock.lock(timeout, timeUnit);
            if (!lock.isLocked()) {
                throw new RedisLockException();
            }
            return executor.execute(null);
        } finally {
            releaseLock(lock);
        }
    }

    @Override
    public void lock(String key, boolean fair, int timeout, TimeUnit timeUnit, VoidExecutor executor) {
        RLock lock = null;
        if (fair) {
            lock = redissonClient.getFairLock(key);
        } else {
            lock = redissonClient.getLock(key);
        }
        try {
            lock.lock(timeout, timeUnit);
            if (!lock.isLocked()) {
                throw new RedisLockException();
            }
            executor.execute();
        } finally {
            releaseLock(lock);
        }
    }

    /**
     * multi lock
     * @param keys lock keys
     * @param timeout timeout
     * @param timeUnit time unit
     * @param executor business executor
     * @return T
     */
    @Override
    public  T multiLock(List keys, int timeout, TimeUnit timeUnit, ReturnableExecutor executor) {
        RLock[] locks = new RLock[keys.size()];
        for (int i = 0; i< keys.size(); i++) {
            locks[i] = redissonClient.getLock(keys.get(i));
        }
        RedissonMultiLock multiLock = new RedissonMultiLock(locks);
        try {
            multiLock.lock(timeout, timeUnit);
            if (!multiLock.isLocked()) {
                throw new RedisLockException();
            }
            return executor.execute(null);
        } finally {
            releaseLock(multiLock);
        }
    }

    /**
     * multi lock
     * @param keys lock keys
     * @param timeout timeout
     * @param timeUnit time unit
     * @param executor business executor
     */
    @Override
    public void multiLock(List keys, int timeout, TimeUnit timeUnit, VoidExecutor executor) {
        RLock[] locks = new RLock[keys.size()];
        for (int i = 0; i< keys.size(); i++) {
            locks[i] = redissonClient.getLock(keys.get(i));
        }
        RedissonMultiLock multiLock = new RedissonMultiLock(locks);
        try {
            multiLock.lock(timeout, timeUnit);
            if (!multiLock.isLocked()) {
                throw new RedisLockException();
            }
            executor.execute();
        } finally {
            releaseLock(multiLock);
        }
    }

    /**
     * multi lock
     * @param keys lock keys
     * @param timeout timeout
     * @param executor business executor
     * @return T
     */
    @Override
    public  T multiLock(List keys, int timeout, ReturnableExecutor executor) {
        return multiLock(keys, timeout, TimeUnit.MILLISECONDS, executor);
    }

    /**
     * multi lock
     * @param keys lock keys
     * @param timeout timeout
     * @param executor business executor
     */
    @Override
    public void multiLock(List keys, int timeout, VoidExecutor executor) {
        multiLock(keys, timeout, TimeUnit.MILLISECONDS, executor);
    }


    /**
     * release lock
     * @param lock lock
     */
    private void releaseLock(RLock lock) {
        if (lock == null) {
            return;
        }
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlockAsync();
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy