fix:主备切换测试
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package com.sunyard.util;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* IP锁工具类 - 高并发安全实现
|
||||
*
|
||||
* 为每个IP地址提供唯一的可重入锁,确保同一IP的操作顺序执行
|
||||
*/
|
||||
public class IpLockUtils {
|
||||
|
||||
private static final ConcurrentMap<String, ReentrantLock> LOCK_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Object CREATION_LOCK = new Object();
|
||||
|
||||
/**
|
||||
* 获取IP对应的锁(保证唯一性)
|
||||
* @param ip IP地址
|
||||
* @return 可重入锁实例
|
||||
*/
|
||||
public static ReentrantLock getLockForIp(String ip) {
|
||||
ReentrantLock lock = LOCK_MAP.get(ip);
|
||||
if (lock != null) {
|
||||
return lock;
|
||||
}
|
||||
|
||||
synchronized (CREATION_LOCK) {
|
||||
// 双重检查
|
||||
lock = LOCK_MAP.get(ip);
|
||||
if (lock == null) {
|
||||
lock = new ReentrantLock(true); // 公平锁
|
||||
LOCK_MAP.put(ip, lock);
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全加锁(带超时机制)
|
||||
* @param ip IP地址
|
||||
* @param timeout 超时时间
|
||||
* @param unit 时间单位
|
||||
* @return 是否成功获取锁
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public static boolean lockWithTimeout(String ip, long timeout, TimeUnit unit)
|
||||
throws InterruptedException {
|
||||
|
||||
ReentrantLock lock = getLockForIp(ip);
|
||||
return lock.tryLock(timeout, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁指定IP的锁
|
||||
* @param ip IP地址
|
||||
*/
|
||||
public static void unlockForIp(String ip) {
|
||||
ReentrantLock lock = LOCK_MAP.get(ip);
|
||||
if (lock != null && lock.isHeldByCurrentThread()) {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理未使用的锁(可选)
|
||||
*/
|
||||
public static void cleanupUnusedLocks() {
|
||||
LOCK_MAP.entrySet().removeIf(entry ->
|
||||
!entry.getValue().isLocked() &&
|
||||
entry.getValue().getQueueLength() == 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前锁数量
|
||||
*/
|
||||
public static int getLockCount() {
|
||||
return LOCK_MAP.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取IP锁状态
|
||||
* @param ip IP地址
|
||||
* @return 锁状态字符串
|
||||
*/
|
||||
public static String getLockStatus(String ip) {
|
||||
ReentrantLock lock = LOCK_MAP.get(ip);
|
||||
if (lock == null) {
|
||||
return "No lock exists";
|
||||
}
|
||||
|
||||
return String.format("Locked: %s, Queue: %d, HoldCount: %d",
|
||||
lock.isLocked(), lock.getQueueLength(), lock.getHoldCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置所有锁
|
||||
*/
|
||||
public static void reset() {
|
||||
synchronized (CREATION_LOCK) {
|
||||
LOCK_MAP.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user