1.锁是什么
一个线程拿到锁,另一个线程就拿不到,满足互斥性。
2.Redis的setnx实现
加锁后解锁,但是要先判断是否是当前线程持有的锁,只能释放本线程的锁。
先判断后释放,两步操作Lua实现原子性
3.为什么要给锁加过期时间
如果持有锁的线程挂了,锁过期自动释放,避免其他线程一直阻塞。
4.线程还没执行完业务,但是锁超时释放了,引入看门狗机制
定时给锁续时间
看门狗线程设置为守护线程,如果业务线程挂了,看门狗也会挂
5.为什么要有锁的重入
递归调用的时候使用,如果是一个线程持有的锁,那么可以重入
synchronized内部有计数器:持有+1,释放-1
ReentrantLock基于AQS,AQS内部有一个state计数器记录
6.分布式锁的实现
redission底层(hsetnx):redis的hash结构:要锁的业务是Key
线程id+UUID=field(集群环境线程id可能重复)
重入次数为value
用redis的String结构,在服务器内部维护CoucurrentHashMap,map的value计数
7.阻塞线程如何拿到锁
ReentrantLock自旋
redission订阅发布:先订阅锁,锁释放后发送订阅信号,阻塞线程可以持有锁
8.主从节点不同步问题
主节点挂了,重新选的从节点升为主节点,但是没有setnx锁信息,就会误判没加锁。
红锁:半数以上的节点加锁才算枷锁成功,满足互斥性