我们现在来到Task类当中,这个方法就是V4了
/**
* Redisson分布式锁实现
* @throws InterruptedException
*/
// @Scheduled(cron="0 */1 * * * ?")//每1分钟(每个1分钟的整数倍)
public void closeOrderTaskV4() throws InterruptedException {
RLock lock = redissonManager.getRedisson().getLock(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
boolean getLock = false;
try {
if(getLock = lock.tryLock(2,50, TimeUnit.SECONDS)){//trylock增加锁
log.info("===获取{},ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,
Thread.currentThread().getName());
int hour = Integer.parseInt(PropertiesUtil
.getProperty("close.order.task.time.hour","2"));
iOrderService.closeOrder(hour);
}else{
log.info("===没有获得分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
}
}finally {
if(!getLock){
return;
}
log.info("===释放分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
lock.unlock();
}
}
V4我们就要用Redisson来搞定分布式锁,其实我们原生实现的单点登陆,使用Spring Session实现单点登陆,原先我们实现的分布式锁,
然后使用Redisson分布式锁都是这么一个过程,先原生实现,然后调用框架实现,本身我们原生实现完之后,基础会更扎实,然后再学习
一些简单的框架呢,也会更快,例如Spring Session侵入性会比较小,那在改造的时候呢,在单位推动这个框架也更容易一些,
使用Redisson来实现这个分布式锁,首先要把之前声明的RedissonManager注入到我们这个类当中,
@Autowired
private RedissonManager redissonManager;
然后直接使用他,首先声明一个RLock,Redisson的一个lock,我们先获取到Redisson这个实例,我们点tryLock,tryLock是尝试获取锁,
也就是我们原来V3讲的版本,这里面尝试获取锁,把这些都封装好了,第一个有参数可以添加等待时间,锁的自动解锁时间,还有时间的
一个单位,首先waittime是什么,尝试获取锁的时候,我最多等待两秒,那多久释放呢,5秒释放,也就是说这个锁最多放5秒,然后最后
写上单位,tryLock的返回值是一个布尔
/**
* Returns <code>true</code> as soon as the lock is acquired.
* If the lock is currently held by another thread in this or any
* other process in the distributed system this method keeps trying
* to acquire the lock for up to <code>waitTime</code> before
* giving up and returning <code>false</code>. If the lock is acquired,
* it is held until <code>unlock</code> is invoked, or until <code>leaseTime</code>
* have passed since the lock was granted - whichever comes first.
*
* @param waitTime the maximum time to aquire the lock
* @param leaseTime lease time
* @param unit time unit
* @return <code>true</code> if lock has been successfully acquired
* @throws InterruptedException - if the thread is interrupted before or during this method.
*/
boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException;
那返回值代表是否获取锁成功,我们在上面给一个默认值,getLock是否获取到锁,默认是false,然后这里面要做一个判断,
那座判断的时候还要给他更新,获取锁并把返回值赋给getLock,如果为true的话就会进入到if里边,我们打印一个日志,
Redisson获取分布式锁,线程的名字,锁的名字,然后还要获取我们的小时,这里面我们就不调用closeOrder了,我们把分布式锁
都交给Redisson来管理了,所以我们这里封装的,包括时间的控制,我们都不需要操作了,我们只把这个时间拿过来,然后可以直接
调用iOrderService.closeOrder(hour),那这个Catch是一个打断的Exception,那这个Catch我们也要打一个日志,
Redisson锁获取异常,这里面需要注意一下,我们要把finally加上,提高一下我们的代码健壮性,如果getLock没有拿到的话,
直接返回,所以我们在finally里面调用unlock来释放这个锁,也就是说,锁用完之后,finally是肯定要执行的,
然后在这里面要释放这个锁了,然后打印一个日志,Redisson分布式锁释放锁,finally一定不要忘记加,提高了我们代码的一个健壮性,
我在tryLock的时候只等一秒,没有的时候就走人了