Discuss / Java / if和return之间发生了写入岂不是读到旧数据了?

if和return之间发生了写入岂不是读到旧数据了?

Topic source

萧雨千叶

#1 Created at ... [Delete] [Delete and Lock User]

检查版本号后没有发生改变,代码没有进入if语句,但是在return之前有数据写入了,这时后面计算Math.sqrt用的就是旧数据了

廖雪峰

#2 Created at ... [Delete] [Delete and Lock User]

你再想想,如果刚执行完return语句时,发生了写入,是不是要再读一遍?你怎么知道发生了写入?

锁的作用是保证读的数据逻辑正确,不会读到一部分写入前的数据一部分写入后的数据

萧雨千叶

#3 Created at ... [Delete] [Delete and Lock User]

也就是这里的锁是保证了x和y读取的原子性,不保证整个方法的原子性,可以这么理解吧

廖雪峰

#4 Created at ... [Delete] [Delete and Lock User]

保证从 tryOptimisticRead 到 validate 之间的代码执行的逻辑完整性,不保证 validate 之后的写入,那个跟你这次读已经无关了

检查版本号后没有发生改变,代码没有进入if语句,但是在return之前有数据写入了,这时后面计算Math.sqrt用的就是旧数据了

补充:我的理解是直接return+结果是原子的,

如果return前有计算过程,就不能保证原子性,也就是不能保证整个方法的原子性,这种情况就会有并发处理数据不一致的问题,

廖老师,我说的对不对,

深刻理解引入乐观锁的目的:

其一:解决读写冲突而为了提交并发效率选择的一种机制,

其二是保证读一致性,牺牲处理数据不一致导致脏数据的可能性可以容忍,适用于不是很严谨的业务逻辑过程中,所有保证读数据一致性就是首要原则,不保证读之后的业务逻辑(悲观锁,缓存锁,应用锁都是在锁内的临界代码内完成并发带来的不完整性不一致性的问题)

退出临界代码块也不是保证到return返回结果的

所以说:具体问题具体对待,具体场景具体分析,

廖雪峰

#7 Created at ... [Delete] [Delete and Lock User]

假设系统有个共享的int x, int y记录鼠标位置,数据变化:

(100, 200), (110, 205), (120, 209), (130, 212)...

你读的时候锁能保证读的x, y是一致的,不会出现(t1时刻的x, t2时刻的y)

至于你读了之后(x, y)也在继续变化,但你不用关心了因为啥也干不了,总不能一直读不return吧?鼠标位置永远在变化中,要等到什么时候?

读了还要处理呢,比如判断x, y是不是在按钮方框内,在就要高亮显示,处理的时候x,y还在继续变化,但那是下一次读-处理的循环要干的事情,跟你这次读的数据无关。

锁只保证逻辑一致性,释放锁以后的后续更新跟这次读的结果已经无关了。


  • 1

Reply