1 Lock锁的设计
/**
* 全局的锁
*/
public class LockHelper {
private static final Logger log = LoggerFactory.getLogger(LockHelper.class);
/**
* 锁类型
*/
public enum LockType {
/**
* 锁 的测试枚举类型
*/
TEST_LOCK_1,
TEST_LOCK_2;
LockType() {
locks.put(this, new ReentrantLock());
}
}
/**
* 保存了所有的锁
*/
private static final Map<LockType, Lock> locks = new HashMap<>();
/**
* 加锁时间,防止死锁
*/
private static final Map<LockType, Date> lockTimeMap = new HashMap<>();
/**
* 如果时长超过两分钟,就去给它解锁
* TODO:这个方法应该放到定时任务,至于怎么继承,就看使用定时任务的人怎么用了
*/
public void run(String args) {
Date now = new Date();
lockTimeMap.forEach((lockType, lockTime) -> {
if (now.getTime() - lockTime.getTime() > TimeUnit.MINUTES.toMillis(2)) {
log.error("这个锁{}两分钟都还没有释放,可能死锁了", lockType);
LockHelper.unlock(lockType);
}
});
}
/**
* 加锁(不带时间,run()方法定时释放锁,避免死锁)
*/
public static void lock(LockType lockType) {
locks.get(lockType).lock();
lockTimeMap.put(lockType, new Date());
}
/**
* 加锁(不带时间,run()方法定时释放锁,避免死锁)
*/
public static boolean tryLock(LockType lockType) {
boolean result = locks.get(lockType).tryLock();
if (result) {
lockTimeMap.put(lockType, new Date());
}
return result;
}
/**
* 加锁(带时间,run()方法定时释放锁,避免死锁)
*/
public static boolean tryLock(LockType lockType, long time, TimeUnit unit) throws InterruptedException {
boolean result = locks.get(lockType).tryLock(time, unit);
if (result) {
lockTimeMap.put(lockType, new Date());
}
return result;
}
/**
* 释放锁(不带时间,需要手动释放,可能会造成死锁)
*/
public static void unlock(LockType lockType) {
locks.get(lockType).unlock();
lockTimeMap.remove(lockType);
}
}
2 使用
@Test
public void testLockHelper() throws InterruptedException {
LockHelper.lock(LockHelper.LockType.TEST_LOCK_1);
// 做一些逻辑处理--------------------------
System.out.println("处理前 testSynchronized");
Thread.sleep(1000);
System.out.println("处理后 testSynchronized");
LockHelper.unlock(LockHelper.LockType.TEST_LOCK_1);
}
@Test
public void testSynchronized() throws InterruptedException {
String orderId = "20190304234124102";
synchronized (orderId.intern()) {
// 做一些逻辑处理--------------------------
System.out.println("处理前 testSynchronized");
Thread.sleep(1000);
System.out.println("处理后 testSynchronized");
}
}