Redis分布式锁处理高并发,据说每秒可以支撑十几万的并发
Redis适合做分布式锁很大原因是因为redis是单线程的
参考网站:http://redis.cn/commands/setnx.html
案例:秒杀多个商品,会访问同一个方法
使用synchronized可以处理并发,但是无法做到细粒度控制,例如秒杀A商品的人很多,秒杀B商品的人很少,会同样的慢,因为访问的同一个方法。只适合单点的情况
使用Redis分布式锁请求比使用synchronized快,但是成功的可能没多少,可以更细粒度的控制,支持分布式
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class RedisLock {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 加锁
* @param key
* @param value 当前时间+超时时间
* @return
*/
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;
}
/**
* 解锁
* @param key
* @param value
*/
public void unlock(String key,String value){
try {
String currentValue = redisTemplate.opsForValue().get(key);
if(!StringUtils.isEmpty(currentValue)&¤tValue.equals(value)){
redisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
log.error("【redis分布式锁】解锁异常,{}",e);
}
}
/**
* 采用分布式锁秒杀商品
*/
public void skillProduct(String productId){
//加锁 设置超时时间为10秒
long time = System.currentTimeMillis()+10*1000;
if(!lock(productId,String.valueOf(time))){
//抛自定义异常(哎哟喂,人也太多了,换个姿势再试试)
}
//查询商品,如果库存为0,则活动结束。如果还有库存则下单并减库存
//解锁
unlock(productId,String.valueOf(time));
}
}
763

被折叠的 条评论
为什么被折叠?



