锁-时序问题
要保证原子操作必须在同一把锁里面,不然会出现不一致的问题
本地锁模拟分布式锁
分布式锁基本原理
实现
阶段一
阶段二
阶段三
加锁要做成原子性,也就是加锁和设置过期时间要是原子性
阶段四
最终
redisson
现在的企业开发一般采用redisson实现分布式锁,分布式对象等功能功能框架
引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.5</version>
</dependency>
配置redis
@Configuration
public class MyredissonConfig {
/**
* 所有对Redisson的使用,都是通过RedissonClient对象
* @return
*/
@Bean(destroyMethod = "shutdown")
public RedissonClient redisson(){
//1、创建配置
Config config = new Config();
config.useSingleServer().setAddress("redis://120.27.210.185:6379");
//2、根据Config创建RedissonClient实例
RedissonClient redissonClient = Redisson.create(config);
return redissonClient;
}
}
实现测试
阻塞式等待就是先原地等待,自旋式就是一直调用自己,直到调用成功。
redisson即使解锁代码没有执行,也不会出现死锁,因为默认设置的加锁过期时间都是三十秒,如果加锁的业务还没有完成,那么锁就会自动续期,这也就是看门狗机制
当然也可以自己设置过期时间,但是要注意自动解锁时间一定要大于业务时间,因为一但自己设置了过期时间,就没有用看门狗机制,就不会自动续期
每隔十秒,就会自动续期到默认的三十秒时间
最佳实战还是采用自定义过期时间
读写锁
信号量
信号量就相当于停车场,每来一辆车就增加一个信号量,可以设置信号量最大值,在项目中,信号量可以用在限流。
闭锁
门卫锁门,等所有人都走了,才可以关门
项目实现
由于锁的名字就决定了锁,所以锁的命名细度越高越好
缓存一致性
双写模式
失效模式
总结
具体使用什么模式,或者什么锁这是要根据需求去分析的