学习基础:
- 了解切面编程,spring AOP注解@Aspect的使用
- 知道如何自定义注解
- 知道如何用redis分布式锁原理 Redis实现分布式锁的7种方案
定义加锁接口
public interface DistributedLock extends Lock {
/**
* 尝试获取分布式锁
*
* @param lockKey 锁
* @param requestId 请求标识
* @param expireSeconds 锁有效时间
* @param overTime 超时时间
* @param timeUnit 时间单位
* @return 是否获取成功
* @throws InterruptedException 中断异常
*/
boolean tryLock(String lockKey, String requestId, int expireSeconds, int overTime, TimeUnit timeUnit) throws InterruptedException;
/**
* 尝试获取分布式分段锁
* @param lockKey
* @param segments 分段标识
* @param requestId
* @param expireSeconds
* @param overTime
* @param timeUnit
* @return 返回成功加锁的段
* @throws InterruptedException
*/
String tryLock(String lockKey, List<String> segments , String requestId, int expireSeconds, int overTime, TimeUnit timeUnit) throws InterruptedException ;
/**
* 释放分布式锁
*
* @param lockKey 锁
* @param requestId 请求标识
*/
boolean unlock(String lockKey, String requestId);
}
实现加锁的方法
加锁本质是为了实现互斥,只让一个访问资源。redis分布式锁是根据lockKey
这个key去查是否有对应的value
,如果值不存在,说明并没有人访问资源,则加锁成功。如果值存在,说明已经有人在访问资源,则加锁失败。
@Component
public class RedisDistributedLock implements DistributedLock {
/**
* 成功
*/
private final static Long SUCCESS = 1L;
/**等待200ms*/
private final static Long WAIT_TIME = 200L;
/**分段锁间的时间间隔*/
private final static Long SEGMENT_WAIT_TIME = 5L;
private final static Long WAIT_TIME_1 = 50L;
/**
* 缓存
*/
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public void lock() {
throw new UnsupportedOperationException();
}
@Override
public void lockInterruptibly() throws InterruptedException {
throw new InterruptedException();
}
@Override
public boolean tryLock() {
throw new UnsupportedOperationException();
}
@Override
public boolean tryLock(String lockKey, String requestId, int expireSeconds, int overTime, TimeUnit timeUnit) throws InterruptedException {
long lastTime = System.nanoTime();
// 获取锁的超时时间
long timeout = timeUnit.toNanos(overTime);
for (; ; ) {
boolean isGet = tryGe