非分佈式鎖的簡易使用
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");
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.