办学质量监测教学评价系统
ageer
2024-02-27 a079ef44e53acd9e8df51dbb31cf5aea4f9be5bd
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
package com.xmzs.midjourney.util;
 
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.thread.ThreadUtil;
import com.xmzs.midjourney.domain.DomainObject;
import lombok.experimental.UtilityClass;
 
import java.time.Duration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
 
@UtilityClass
public class AsyncLockUtils {
    private static final TimedCache<String, LockObject> LOCK_MAP = CacheUtil.newTimedCache(Duration.ofDays(1).toMillis());
 
    public static synchronized LockObject getLock(String key) {
        return LOCK_MAP.get(key);
    }
 
    public static LockObject waitForLock(String key, Duration duration) throws TimeoutException {
        LockObject lockObject;
        synchronized (LOCK_MAP) {
            if (!LOCK_MAP.containsKey(key)) {
                LOCK_MAP.put(key, new LockObject(key));
            }
            lockObject = LOCK_MAP.get(key);
        }
        Future<?> future = ThreadUtil.execAsync(() -> {
            try {
                lockObject.sleep();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        try {
            future.get(duration.toMillis(), TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            // do nothing
        } catch (TimeoutException e) {
            future.cancel(true);
            throw new TimeoutException("Wait Timeout");
        } finally {
            LOCK_MAP.remove(lockObject.getId());
        }
        return lockObject;
    }
 
    public static class LockObject extends DomainObject {
 
        public LockObject(String id) {
            this.id = id;
        }
    }
}