分布式系统是跨虚拟机的,jvm的锁不管用,所以需要分布式锁。
实现的要求有:
1.多进程可见,不然怎么标记
2.避免死锁,就是保证锁可以释放
3.排他
4.服务器宕机怎么补救
实现的方式很多,和java服务独立的有很多东西,比如redis、数据库、zookeeper....
简单记录一种利用redis实现的方法。
1.redis本身就是多服务共享的,满足 2.排他 让他执行 setnx aa bb,这哥们第一次执行会返回1,有了之后执行返回0,返回1我们就知道我们获取到锁了 3.避免死锁 可以给这key设置过期时间,到期自动被删除 4.补救可以利用redis的主从、哨兵
好像不对,随便设置个key-value有问题
为什么,因为比如一个进程A执行,拿到锁,执行比较耗时,结果锁到时间了被删除了,进程B获取到了锁开始执行,然后进程A执行完了,执行del删除锁,然后进程C又获取了。 这有一个问题,不是自己的锁请不要删除,所以可以设置自己的线程Id,aa 线程信息,每次删除前比较下是不是自己的。
还是不对,这锁不是可重入锁,应该使用hash结构
key aa 线程信息 次数,当次数减成0才可以del
还是有问题你的判断逻辑不是原子操作
我觉得可以把逻辑改成lua脚本执行
最后发现已经有Redission了
@Autowired
private RedissonClient redissonClient;
public void test() {
// 创建锁对象,并制定锁的名称
RLock lock = redissonClient.getLock("aa");
// 获取锁,设置自动失效时间为30s
boolean isLock = lock.tryLock();
// 判断是否获取锁
if (!isLock) {
// 获取失败
return;
}
try {
} catch (InterruptedException e) {
} finally {
// 释放锁
lock.unlock();
}
}