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 obj = new ConcurrentHashMap<>(); private Map 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); } }