加入redis依赖和配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b2e5c1f4c3c78d5e6b6c9d8596a0d07c.png)
两个关键的方法
redisTemplate.opsForValue().setIfAbsent(key, value)
String oldValue = redisTemplate.opsForValue().getAndSet(key, value);
redisTemplate.opsForValue().getOperations().delete(key)
实现redis分布式锁
package com.imooc.service;
@Component
@Slf4j
public class RedisLock {
@Autowired
private StringRedisTemplate redisTemplate;
public boolean lock(String key,String value){
if(redisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
String currentValue = redisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {
String oldValue = redisTemplate.opsForValue().getAndSet(key, value);
if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
return true;
}
}
return false;
}
public void unlock(String key, String value) {
try {
String currentValue = redisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
redisTemplate.opsForValue().getOperations().delete(key);
}
}catch (Exception e) {
log.error("【redis分布式锁】解锁异常, {}", e);
}
}
}
业务代码
@Override
public void orderProductMockDiffUser(String productId)
{
long time = System.currentTimeMillis()+TIMEOUT;
if(!redisLock.lock(productId,String.valueOf(time))){
throw new SellException(101,"抢的人太多了,换个姿势试试");
}
int stockNum = stock.get(productId);
if(stockNum == 0) {
throw new SellException(100,"活动结束");
}else {
orders.put(KeyUtil.genUniqueKey(),productId);
stockNum =stockNum-1;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
stock.put(productId,stockNum);
}
redisLock.unlock(productId,String.valueOf(time));
}