linwe
2024-09-03 764d883b5ea3bdc06abbec548b6df0511e567978
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
package org.springblade.common.utils;
 
import org.springblade.core.redis.cache.BladeRedis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
 
@Component
public class SpinLockUtil {
    @Autowired
    private BladeRedis bladeRedis;
 
    private static final String LOCK_PREFIX = "thread-safe-lock:";
    private static final Long DEFAULT_LOCK_TIMEOUT = 6L; // 默认锁超时时间,单位:秒
 
 
    /**
     * 尝试获取锁,如果获取失败则自旋等待。
     *
     * @param lockKey 锁的键
     * @return 是否成功获取锁
     */
    public boolean tryLock(String lockKey) {
        String threadId = Thread.currentThread().getName() + Thread.currentThread().getId(); // 使用线程名和ID作为标识
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < DEFAULT_LOCK_TIMEOUT * 1000) {
            if (bladeRedis.getRedisTemplate().opsForValue().setIfAbsent(LOCK_PREFIX + lockKey, threadId,
                DEFAULT_LOCK_TIMEOUT, TimeUnit.SECONDS)) {
                return true;
            }
            // 短暂休眠,避免高并发下的CPU过度消耗
            LockSupport.parkNanos(100_000_000L); // 使用LockSupport进行更细粒度的暂停,单位为纳秒
        }
        return false;
    }
 
    /**
     * 释放锁,只有加锁的线程才能解锁
     *
     * @param lockKey 锁的键
     * @return 是否成功释放锁
     */
    public boolean unlock(String lockKey) {
        String threadId = Thread.currentThread().getName() + Thread.currentThread().getId();
        String currentValue = (String) bladeRedis.getRedisTemplate().opsForValue().get(LOCK_PREFIX + lockKey);
        if (threadId.equals(currentValue)) {
            bladeRedis.getRedisTemplate().delete(LOCK_PREFIX + lockKey);
            return true;
        }
        return false; // 如果不是当前线程持有的锁,则返回false,不进行解锁操作
    }
 
}