T100738
2024-04-16 eeb86aaf2f73a02600195ce2637dde6caf858a88
product-server-data-center/src/main/java/com/product/data/center/utils/CustomLock.java
@@ -1,12 +1,18 @@
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
@@ -16,87 +22,140 @@
public class CustomLock {
    private Set<String> obj = new ConcurrentHashSet<>();
   private Map<String, Long> obj = new ConcurrentHashMap<>();
   private Map<String, Long> threadObj = new ConcurrentHashMap<>();
    private long detectionWaitTime = 1000L;
   private long detectionWaitTime = 1000L;
    /**
     * 无参构造时
     */
    public CustomLock() {
    }
   /**
    * 无参构造时
    */
   public CustomLock() {
   }
    /**
     * @param detectionWaitTime 检测等待时间,单位毫秒
     */
    public CustomLock(long detectionWaitTime) {
        this.detectionWaitTime = detectionWaitTime;
    }
   /**
    * @param detectionWaitTime 检测等待时间,单位毫秒
    */
   public CustomLock(long detectionWaitTime) {
      this.detectionWaitTime = detectionWaitTime;
   }
    public boolean tryLock(String[] key) {
        return this.tryLock(ArrayUtil.join(key, ","));
    }
   public boolean tryLock(String[] key) {
      return this.tryLock(ArrayUtil.join(key, ","));
   }
    public boolean tryLock(String key) {
        if (!StringUtils.isEmpty(key)) {
            key = key.toUpperCase();
            synchronized (key.intern()) {
                if (!this.obj.contains(key)) {
                    lock(key);
                    return true;
                }
            }
        }
        return false;
    }
   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 void lock(String... key) {
        this.lock(ArrayUtil.join(key, ","));
    }
   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) {
        String obj = key;
        if (StringUtils.isEmpty(obj)) {
            return;
        }
        obj = obj.toUpperCase();
   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.contains(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);
                }
            }
      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);
        }
         ThreadUtil.sleep(this.detectionWaitTime);
      }
//        if (enterLock) {
//            SpringMVCContextHolder.getSystemLogger().info("等待定时间:" + (System.currentTimeMillis() - starTime) + " ms,lockKey:" + obj);
//        }
//        SpringMVCContextHolder.getSystemLogger().info("上锁成功,lockKey:" + obj);
        this.obj.add(obj);
    }
      this.obj.put(obj, System.currentTimeMillis());
   }
    public void unLock(String... key) {
        String obj = ArrayUtil.join(key, ",");
        unLock(obj);
    }
   public void unLock(String... key) {
      String obj = ArrayUtil.join(key, ",");
      unLock(obj);
   }
    public void unLock(String key) {
   public void unLock(String key) {
        if (StringUtils.isEmpty(key)) {
            return;
        }
        this.obj.remove(key.toUpperCase());
      if (StringUtils.isEmpty(key)) {
         return;
      }
      this.obj.remove(key.toUpperCase());
//        SpringMVCContextHolder.getSystemLogger().info("释放锁成功,lockKey:" + key);
    }
   }
}