许鹏程
2024-05-15 3212d131b28e5f4b09bb1222861370310a00ffc9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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);
    }
 
 
}