读写锁
顾名思义,就是分为读锁跟写锁,读锁共享写锁互斥,其核心思想为:
- 读读共享
- 读写互斥
- 写写互斥
锁结构
存储为hash 为了区分读锁还是写锁,所以还需要一个key来标识当前锁是是读锁还是写锁
- mode:read/write
- uuid:threadId:1 唯一标识:重入次数
- timeout:3000 过期时间
读锁加锁
特点读读共享
- 第一次读锁进入:
- mode:read
- uuid:threadId:1
- timeout:3000
- 第二次读锁进入:
- 判断是自己的锁则重入次数+1,刷新过期时间
- mode:read
- uuid:threadId:2
- uuid:threadId:timeout:3000
- 不是自己的锁则:
- mode:read
- uuid:threadId:1
- uuid:threadId:timeout:3000
- uuid:threadId2:1
- uuid:threadId2:timeout:3000
- 判断是自己的锁则重入次数+1,刷新过期时间
写锁加锁
特点读写互斥,写写互斥
- 第一次写锁进入
- mode:write
- uuid:threadId:1
- timeout:3000
- 第二次写锁进入
- 判断是自己的锁则重入次数+1,刷新过期时间
- mode:write
- uuid:threadId:2
- 判断不是自己的锁
- 加锁失败
- 判断是自己的锁则重入次数+1,刷新过期时间
- 加了写锁后,后面进来只要不是自己的锁统统加锁失败
锁释放
- 释放时,不能直接删除key,更不能直接删除整个hash,要考虑重入和非重入
读锁释放
- 重入
- 重入次数-1
- 非重入
- 删除key和自己的timeout
- 判断hash除了mode外是否还有别的线程,如果没有直接删除这个hash
写锁释放
- 重入
- 重入次数-1
- 非重入
- 因为写锁没有timeout,所以直接删除整个hash就可以
watchDog
就像上面例子中的,续期时间的设置主要是两方面
- 整个hash的有效时间
- hash中key的有效时间(写锁只有自己,所以没有timeout) 重入的时候刷新hash和对应key的有效时间。
- 写锁互斥,所以只需要给整个hash设置有效时间就可以了
- 读读共享,所以不进要设置整个hash的有效时间,同时也要设置每个线程的有效时间