分布式锁是啥,就是在分布式环境下来进行资源的锁定,在单台tomca下面,一般没有这种竞争条件,但是多台tomcat就有了竞争条件了,例如定时任务,不可能让多个tomcat 都去执行定时任务....
Redisson分布式锁,就是对唯一管理,获取到了就获取到了锁,没有得到就没获取锁,不能执行,当然了,还涉及到锁的释放,超时等
当然了,我们也可以自己使用redis自己写一个分布式锁,是没有问题的,这次先不说这块,这次说的是一个牛逼的框架,属于二次开发,在redis的基础上开发得到的Redisson.
1.添加依赖:
org.redisson
redisson
3.8.2
2.添加配置文件:
由于使用的springoot作为开发环境,所有自定义bean进行注入:
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient getClient(){
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
return redisson;
}
}
本次使用单机的redis作为测试用例,只有一个几点,Redisson支持集群模式的redis.
3.实现分布式锁:
RLock lock = redisson.getLock("lockName");
try{
// 1. 最常见的使用方法
//lock.lock();
// 2. 支持过期解锁功能,10秒钟以后自动解锁, 无需调用unlock方法手动解锁
//lock.lock(10, TimeUnit.SECONDS);
// 3. 尝试加锁,最多等待2秒,上锁以后8秒自动解锁
boolean res = lock.tryLock(2, 8, TimeUnit.SECONDS);
if(res){ //成功
//处理业务
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
当然了,这是redisson 的最基本的用法,Redisson实现了很多,还有很多的东西,可以去慢慢发现.
补充上自己手写实现redis分布式锁的方法:2018年12月4日17:15:27
long lockTimeOut=5000L;
String lockName="lock";
Long setnx = RedisSharedPoolUtil.setnx(lockName, String.valueOf(System.currentTimeMillis() + lockTimeOut));
if(setnx !=null && setnx.intValue()==1){
//返回值是1,表示成功,获取锁
//do something
}else {
//为获取到锁,继续判断,看能否重置,并且获取到锁.
String s = RedisSharedPoolUtil.get(lockName);
if(s!=null && System.currentTimeMillis()>Long.parseLong(s)){
//不为空,而且已经超时了 //重置锁
//上面的s 和这个set有可能不一样,因为是集群tomcat.返回给定的key,->旧值判断,是否可以获取锁
//当key没有旧值时,即key不存在,返回nil->获取锁
//这里我们set了一个新value,获取旧值
String set = RedisSharedPoolUtil.getSet(lockName, String.valueOf(System.currentTimeMillis() + lockTimeOut));
if(set== null || (set!=null && StringUtils.equals(s,set))){
//真正获取到锁
//do something
}else{
log.info("没有获取到分布式锁:{}",lockName);
}
}else {
log.info("没有获取到分布式锁:{}",lockName);
}
log.info("没有获取到分布式锁:{}",lockName);
}
log.info("完成定时关闭订单的任务");
如果您觉得写得不多, 可以请作者喝一杯咖啡