package com.product.data.center.utils;
|
|
import cn.hutool.core.collection.ConcurrentHashSet;
|
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.thread.ThreadUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
import com.product.core.spring.context.SpringMVCContextHolder;
|
import org.apache.commons.lang3.StringUtils;
|
|
import javax.swing.*;
|
import java.text.DateFormat;
|
import java.util.Date;
|
import java.util.Map;
|
import java.util.Set;
|
import java.util.concurrent.ConcurrentHashMap;
|
|
/**
|
* @Author cheng
|
* @Date 2022/11/14 11:30
|
* @Desc
|
*/
|
public class CustomLock {
|
|
|
private Map<String, Long> obj = new ConcurrentHashMap<>();
|
private Map<String, Long> threadObj = new ConcurrentHashMap<>();
|
|
|
private long detectionWaitTime = 1000L;
|
|
|
/**
|
* 无参构造时
|
*/
|
public CustomLock() {
|
}
|
|
/**
|
* @param detectionWaitTime 检测等待时间,单位毫秒
|
*/
|
public CustomLock(long detectionWaitTime) {
|
this.detectionWaitTime = detectionWaitTime;
|
}
|
|
public boolean tryLock(String[] key) {
|
return this.tryLock(ArrayUtil.join(key, ","));
|
}
|
|
public static void main(String[] args) {
|
long timemillis = 1709654400039L;
|
//转换为年月日时分秒
|
String format = DateUtil.format(DateUtil.date(timemillis), "yyyy-MM-dd HH:mm:ss");
|
|
System.out.println(format);
|
}
|
|
public boolean tryLock(String key, long timeoutMinute) {
|
if (!StringUtils.isEmpty(key)) {
|
key = key.toUpperCase();
|
synchronized (key.intern()) {
|
if (!this.obj.containsKey(key)) {
|
lock(key);
|
//获取当前线程
|
long id = Thread.currentThread().getId();
|
threadObj.put(key, id);
|
return true;
|
} else if (timeoutMinute > 0) {
|
//获取锁进入开始时间
|
long startTime = obj.get(key);
|
//获取当前时间
|
long currentTime = System.currentTimeMillis();
|
|
//将分钟转换为毫秒
|
long timeout = timeoutMinute * 60 * 1000;
|
//如果当前时间减去开始时间大于等于超时时间
|
if (currentTime - startTime >= timeout) {
|
long threadId = threadObj.get(key);
|
//根据线程id获取线程
|
Thread[] threads = ThreadUtil.getThreads();
|
for (Thread thread : threads) {
|
if (thread.getId() == threadId) {
|
//中断线程
|
ThreadUtil.interrupt(thread, true);
|
SpringMVCContextHolder.getSystemLogger().error("线程:" + thread.getName() + "超时被中断");
|
return tryLock(key, timeoutMinute);
|
}
|
}
|
return true;
|
}
|
|
}
|
}
|
}
|
return false;
|
}
|
|
|
public boolean tryLock(String key) {
|
if (!StringUtils.isEmpty(key)) {
|
key = key.toUpperCase();
|
synchronized (key.intern()) {
|
if (!this.obj.containsKey(key)) {
|
lock(key);
|
//获取当前线程
|
long id = Thread.currentThread().getId();
|
threadObj.put(key, id);
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
|
public void lock(String... key) {
|
this.lock(ArrayUtil.join(key, ","));
|
}
|
|
public void lock(String key) {
|
String obj = key;
|
if (StringUtils.isEmpty(obj)) {
|
return;
|
}
|
obj = obj.toUpperCase();
|
// boolean enterLock = false;
|
long starTime = System.currentTimeMillis();
|
Long outLogTime = null;
|
while (this.obj.containsKey(obj)) {
|
if (System.currentTimeMillis() - starTime >= (1000 * 60 * 5)) {
|
if (outLogTime == null || System.currentTimeMillis() - outLogTime >= (1000 * 60)) {
|
outLogTime = System.currentTimeMillis();
|
SpringMVCContextHolder.getSystemLogger().error("等待释放锁时间超过5分钟,等待时间:" + (System.currentTimeMillis() - starTime) + "ms,lockKey:" + obj);
|
}
|
}
|
// enterLock = true;
|
// SpringMVCContextHolder.getSystemLogger().info("锁释放等待,lockKey:" + obj);
|
ThreadUtil.sleep(this.detectionWaitTime);
|
}
|
// if (enterLock) {
|
// SpringMVCContextHolder.getSystemLogger().info("等待定时间:" + (System.currentTimeMillis() - starTime) + " ms,lockKey:" + obj);
|
// }
|
// SpringMVCContextHolder.getSystemLogger().info("上锁成功,lockKey:" + obj);
|
this.obj.put(obj, System.currentTimeMillis());
|
}
|
|
public void unLock(String... key) {
|
String obj = ArrayUtil.join(key, ",");
|
unLock(obj);
|
}
|
|
public void unLock(String key) {
|
|
if (StringUtils.isEmpty(key)) {
|
return;
|
}
|
this.obj.remove(key.toUpperCase());
|
// SpringMVCContextHolder.getSystemLogger().info("释放锁成功,lockKey:" + key);
|
}
|
|
|
}
|