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,不进行解锁操作 } }