当前位置 博文首页 > A_art_xiang的博客:如何用redis实现分布式锁?这篇文章教你用re
?
import org.redisson.Redisson;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* redisson 配置类
*/
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private String port;
@Value("${spring.redis.password}")
private String password;
@Bean
public Redisson getRedisson(){
Config config = new Config();
config.useSingleServer().setAddress("redis://" + host + ":" + port);//.setPassword(password);
//添加主从配置
// config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});
return (Redisson) Redisson.create(config);
}
}
@RequestMapping("/redisson")
public String redisson(){
String lockKey = "product_001";//商品id作为锁
RLock lock = redisson.getLock(lockKey);
try{
//这里如果其他线程加锁失败,会while一直循环阻塞
//同时在后台起一个线程,每隔10秒(1/3的超时时间)会判断这把锁是否释放,如果未释放则刷新超时时间
System.out.println("准备尝试获取锁");
lock.lock(30, TimeUnit.SECONDS);
System.out.println("进来了,开始停8秒");
Thread.sleep(8000);
//这里写逻辑
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return "success";
}
1.使用redis设置过期时间(假如10秒),redisson会又一个监听线程,每隔一段时间(一般10*2/3=6秒)会刷新这个key的过期时间,防止业务没有执行完就释放了锁。
2.设置过期时间的目的:防止系统突然挂掉,死锁。时间一过就可以释放锁。
3.当锁已经被获取之后,会一直不断地尝试获取锁(自旋锁),直到锁获取成功,执行业务逻辑。
4.锁的key一般就是用业务的流水号,或者商品的编号,唯一的。
1.高并发下实现串行化。
2.实现幂等性(需要在代码中进行判断)。
1.降低系统性能。
2.系统繁杂更容易出现问题,不好维护。
?
cs