很多人看代码的时候,可能比较疑惑,为什么要加读写锁。
raft处理写请求的流水线的消费者都是单线程的,完全没有并发问题,但是还要处理读请求了,如果写了一半的被读的线程看到了,数据就不准了。同时为了高性能,就使用读写锁了。
1 写请求,加写锁

2 读请求,加读锁

3 相关流程都加读写锁
NodeImpl是流程的入口,流程的其他环境也都是类似的,这里就不赘述了。
4 设计的利弊
很多地方都要考虑要不要加锁,加读锁还是写锁,加的锁还要保证正常释放掉。对人的心智负担还是有些的。
我们一些场景的做法是:把要操作的数据聚焦到一个对象,用copy-on-write的思想,复制一份改完,指像新的引用。这样就不用加锁了。对于这种读多写少的情况也是挺适合的。
不过copy-on-write的关键在于:
1 能不能把要修改的数据聚集起来
2 对象是不是很大,大对象复制的成本不小,对gc也会有些压力
网友评论