com.vikadata.social.core.RedisTemplateSimpleDistributedLock Maven / Gradle / Ivy
The newest version!
package com.vikadata.social.core;
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.core.types.Expiration;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import org.springframework.lang.NonNull;
/**
* Implement simple redis distributed lock, support reentrancy, not Redlock
*/
public class RedisTemplateSimpleDistributedLock implements Lock {
private final StringRedisTemplate redisTemplate;
private final String key;
private final int leaseMilliseconds;
private final ThreadLocal valueThreadLocal = new ThreadLocal<>();
/**
* constructor.
*
* @param redisTemplate RedisTemplate
* @param key Lock key
* @param leaseMilliseconds The lease time of the lock, in milliseconds
*/
public RedisTemplateSimpleDistributedLock(StringRedisTemplate redisTemplate, String key,
int leaseMilliseconds) {
if (leaseMilliseconds <= 0) {
throw new IllegalArgumentException(
"Parameter 'leaseMilliseconds' must grate then 0: " + leaseMilliseconds);
}
this.redisTemplate = redisTemplate;
this.key = key;
this.leaseMilliseconds = leaseMilliseconds;
}
@Override
public void lock() {
while (!tryLock()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
}
@Override
public void lockInterruptibly() {
while (!tryLock()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
}
@Override
public boolean tryLock() {
String value = valueThreadLocal.get();
if (value == null || value.isEmpty()) {
value = UUID.randomUUID().toString();
valueThreadLocal.set(value);
}
final byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
final byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
List