因为redis是单线程程序,可以天然保证线程安全,只要我们的命令是单条命令,就可以保证操作的安全性,而redis中提供了setnx key value命令,表示当redis中没有key 的键值对时,就会创建这个键值对的值,如果已经有了,就不操作,java中有valueOperations.setIfAbsent(key,value)与redis中的setnx是一样的作用。我们可以使用valueOperations.setIfAbsent实现分布式加锁的操作,也可以给锁设置过期时间,这样就算客户端故障也能在过期时间之后释放锁
Boolean isLock=valueOperations.setIfAbsent("k1",value,120,TimeUnit.SECONDS);
key是任意值,value保证每个使用者唯一性即可,便于锁的释放,因为我们在释放锁也就是del key时,需要保证只有真正获得锁的程序才能去释放对应的锁,而不是谁都可以进行锁的释放,防止自己获得锁被别人释放了,所以我们释放锁的步骤就是:
- 先判断锁变量的值,是否是自己获得锁
- 如果是自己获取的锁,就可以进行锁的释放
- 如果不是自己获取的锁,就无法进行锁的释放
这就不是一个命令了,但是我们需要这些命令原子性执行,所以就用到了lua脚本。Redis对lua脚本的调用是原子性的,所以一些特殊场景,可以放在lua中实现,这里记录下来一个简单的例子
首先在resources目录下创建一个lock.lua文件
if redis.call("get",KEYS[1])==ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
当输入的key[1]在redis中等于输入的argv[1]时,删除这个原有的key,即释放锁,不等则无法释放锁 key[1]:获取锁时输入的key,argv[1]:获取锁时输入的value
@Test
public</