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值。我觉得这里是有问题的,请老师解答。
1回答
-
Geely
2018-01-16
你好同学,我们挨个来仔细看一下
首先 多个线程同时进入else。这说明有另外一个线程我们叫A,A线程是进入到IF里面,所以A线程拿到锁。
接着说进入else里面的B和C。首先会get一下,拿出来。如果判断当前时间不大于的话,就不会进入到else里面的if对吧。所以这里面有一个问题,就是我们设置锁的时间,最好的是大于任务执行的时间,但是也不能大于太多。避免异常情况,防止死锁。
然后我们继续来说。如果重置了,那么equal那个B和C不会都相当的。所以这块同时进入else里面的BC线程 也不会同时获取到锁的。
012018-07-31
相似问题