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