何避免并发出现的超卖情况?
synchronized关键字
在单个jvm运行的情况下可以使用。
Q:多个jvm的情况下怎么办?
使用redis分布式锁
redis setnx 命令
根据setnx命令的特性可以实现加锁的效果
在删除锁之前可能会发生异常因此应该加上try finally,在finally中删除锁
在删除锁之前jvm挂了 这时就需要在setnx的时候设置一个过期时间
lock()方法=setIfAbsent()方法
务必将赋值与设置过期时间写成一条语句保持原子性
由于锁是公共的,可能会出现删除锁会删到别的线程在使用的锁。所以可以加一个标识来鉴别是否是当前线程的锁
业务代码没有执行完锁过期了怎么办?
锁续约,设置好过期时间后开启一个分支线程来监听锁的状态。每隔一段时间查询锁是否存在,存在的话重新设置过期时间。
可使用 Redisson
https://github.com/redisson/redisson#quick-start
redis主从结构还会有问题:当Redisson向主redis发送加锁请求还没来得及同步到从redis时,主redis挂了锁就没有了。
提升redis分布式锁的性能可以用库存分段的方式。