一、线程阻塞

例如,线程一获取分布式锁,但是线程一阻塞时间过长,导致锁超时释放。此时线程二获取分布式锁。当线程一阻塞结束后,释放分布式锁,但是释放的却是线程二的锁。此时线程二就不安全了,线程三也可以并发执行。解决这个问题,可以在释放锁的时候判断一下Redis中存的锁是不是自己的锁,只有匹配才释放。

Redis:分布式锁误删原因分析-LMLPHP

Redis:分布式锁误删原因分析-LMLPHP

二、垃圾回收机制

这是一种比较极端的情况。线程一正常执行,当判断锁是否一致并且结果为一致时,还没有来得及释放锁,JVM正好触发类似full gc的垃圾回收机制,此时阻塞,直至分布式锁超时释放。线程二进入,当gc完成时,线程一由于之前已经判断一致,还是释放了锁,就又出现了线程并发安全问题。这里我们需要做的是将判断和释放锁过程合并设置为原子性操作。

Redis:分布式锁误删原因分析-LMLPHP

09-15 05:47