import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.LongCodec;
import org.redisson.config.Config;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class RedissonLockTest {
public static final String REDISSON_LOCK = "redisson";
public static void main(String[] args) throws InterruptedException {
RedissonClient redissonClient = redissonClient();
try {
RLock rLock = redissonClient.getLock(REDISSON_LOCK);
// 嘗試鎖定
rLock.tryLock();
printLog("using lock.");
// 創建一個新的線程
List.of(3,5).forEach(o -> newAThread(redissonClient, o));
// newAThread(redissonClient);
int second = 5;
printLog(String.format("sleep %s(s).", second));
TimeUnit.SECONDS.sleep(second);
// 如果當前線程鎖住並且持有該鎖
if (rLock.isLocked() && rLock.isHeldByCurrentThread())
rLock.unlock();
printLog("release lock success.");
} catch (Exception e) {
e.printStackTrace();
} finally {
TimeUnit.SECONDS.sleep(20);
// 關閉 Redisson 客戶端
redissonClient.shutdown();
}
TimeUnit.SECONDS.sleep(2);
System.exit(0);
}
public static void newAThread(RedissonClient redissonClient, int i) {
new Thread(() -> {
try {
// 創建一個 Redisson 分布式鎖
RLock anotherLock = redissonClient.getLock(REDISSON_LOCK);
// 創建一個 Redisson 訂閱主題
RTopic topic = redissonClient.getTopic("redisson_lock__channel:{redisson}", LongCodec.INSTANCE);
// RPatternTopic patternTopic = redissonClient.getPatternTopic("*", LongCodec.INSTANCE); // 亦可使用Regex 方式
// 添加訂閱者到訂閱主題
int topicId = topic.addListener(Long.class, (channel, msg) -> printLog(String.format("RTopic => channel:%s, message:%s", channel, msg)));
// 嘗試鎖住
// boolean lockSuccess = anotherLock.tryLock(2, TimeUnit.SECONDS);
boolean lockSuccess = anotherLock.tryLock(5, 1, TimeUnit.SECONDS); // 等待時間內收到釋放鎖消息,則重新去競爭鎖
// boolean lockSuccess = anotherLock.tryLock(2, 1, TimeUnit.SECONDS); // 等待時間內未獲得鎖直接回傳結果。
// boolean lockSuccess = anotherLock.tryLock(); // 未設置等待時間,則直接判斷當前是否取到鎖
if (lockSuccess) {
printLog("try lock success.");
TimeUnit.SECONDS.sleep(i);
// 如果當前線程鎖住並且持有該鎖
if (anotherLock.isLocked() && anotherLock.isHeldByCurrentThread()) {
anotherLock.unlock();
printLog("release lock success.");
}
} else {
printLog("try lock failed.");
}
// 移除訂閱者
topic.removeListener(topicId);
} catch (Exception e) {
e.printStackTrace();
}
}, "Thread_" + i).start();
}
static void printLog(String message) {
System.out.println(String.format("%s - [%s] -> %s", LocalDateTime.now(), Thread.currentThread().getName(), message));
}
private static RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://172.20.160.120:6379");
config.setLockWatchdogTimeout(TimeUnit.SECONDS.toMillis(10));
return Redisson.create(config);
}
}