public double distanceFromOrigin() { long stamp = stampedLock.tryOptimisticRead(); // 获得一个乐观读锁 // 注意下面两行代码不是原子操作 // 假设x,y = (100,200) double currentX = x; // 此处已读取到x=100,但x,y可能被写线程修改为(300,400) double currentY = y; // 此处已读取到y,如果没有写入,读取是正确的(100,200) // 如果有写入,读取是错误的(100,400) if (!stampedLock.validate(stamp)) { // 检查乐观读锁后是否有其他写锁发生 stamp = stampedLock.readLock(); // 获取一个悲观读锁 try { currentX = x; currentY = y; } finally { stampedLock.unlockRead(stamp); // 释放悲观读锁 } } return Math.sqrt(currentX * currentX + currentY * currentY); }
关于这块代码,想问问老师,这里释放悲观读锁之后
stampedLock.unlockRead(stamp); // 释放悲观读锁
返回以下结果之前
return Math.sqrt(currentX * currentX + currentY * currentY);
有一个写线程获取到了锁,并把(x,y)从(1,2)变成了(3,4),但是此线程读到的结果是 Math.sqrt(1*1 + 2*2),这算不算返回了错误数据呢?
卡极限操作是吧
你这个疑问之前已经有人问过了,往下看@萧雨千叶的提问:if和return之间发生了写入岂不是读到旧数据了?廖老师对此也回复解释得非常清楚,建议看看。
我的理解是不会,读数据要重新获取锁
锁的作用是保证,这个是一个原子操作
currentX = x; currentY = y;
你说的那个顶多算过时的数据,不是错误数据。
Sign in to make a reply
不惑之年
关于这块代码,想问问老师,这里释放悲观读锁之后
返回以下结果之前
有一个写线程获取到了锁,并把(x,y)从(1,2)变成了(3,4),但是此线程读到的结果是 Math.sqrt(1*1 + 2*2),这算不算返回了错误数据呢?