getSet问题

来源:14-3 分布式锁双重防死锁演进

慕雪3203975

2018-01-14

老师,有个问题,就是多线程环境下,getSet这里的处理我觉得有点问题。

分布式锁双重防死锁演进这一节中,假如两个线程都走到了else代码块,判断锁超时了,进入了if语句,接下来两个线程要先后执行getSet方法了。然后第一个线程执行RedisShardedPoolUtil.getSet(Const.RedisLock.CLOSE_ORDER_TASK_LOCK, String.valueOf(System.currentTimeMillis() + lockTimeout))将锁的value重置,然后进入if语句执行关单的closeOrder方法,紧接着第二个线程走到getSet这里,get了旧值(第一个线程重置的value值),然后又重置(set)了锁的value值!!!旧值和最开始的lockValueStr不相等,第二个线程获取锁失败,但是,这里第二个线程却重置了第一个线程设置的锁的value值,我觉得第一个线程设置好的锁的value值是不应该被改变的,但这里第二个线程确实可以改变第一个线程的锁的value值。我觉得这里是有问题的,请老师解答。

//img.mukewang.com/szimg/5a5b3511000136d220880796.jpg

写回答

1回答

Geely

2018-01-16

你好同学,我们挨个来仔细看一下

首先 多个线程同时进入else。这说明有另外一个线程我们叫A,A线程是进入到IF里面,所以A线程拿到锁。

接着说进入else里面的B和C。首先会get一下,拿出来。如果判断当前时间不大于的话,就不会进入到else里面的if对吧。所以这里面有一个问题,就是我们设置锁的时间,最好的是大于任务执行的时间,但是也不能大于太多。避免异常情况,防止死锁。

然后我们继续来说。如果重置了,那么equal那个B和C不会都相当的。所以这块同时进入else里面的BC线程 也不会同时获取到锁的。



0
1
慕哥3504082
老师,同时进入else的BC线程只有一个能获取到锁,假设B线程getset之后满足后面的equals条件,那么C线程必然不会满足equals条件,但是有一个问题,C线程仍然执行getset方法,重置了B设置好的value值,这一点有疑惑
2018-07-31
共1条回复

Java企业级电商项目架构 Tomcat集群与Redis分布式

Tomcat集群+Redis分布式+代码重构+源码原理解析

2685 学习 · 947 问题

查看课程