首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我们不需要StampedLock的易失性呢?

为什么我们不需要StampedLock的易失性呢?
EN

Stack Overflow用户
提问于 2017-08-30 09:05:54
回答 2查看 447关注 0票数 11

给出了Oracle https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/StampedLock.html中的代码示例

代码语言:javascript
复制
class Point {
   private double x, y;
   private final StampedLock sl = new StampedLock();

   void move(double deltaX, double deltaY) { // an exclusively locked method
     long stamp = sl.writeLock();
     try {
       x += deltaX;
       y += deltaY;
     } finally {
       sl.unlockWrite(stamp);
     }
   }

   double distanceFromOrigin() { // A read-only method
     long stamp = sl.tryOptimisticRead();
     double currentX = x, currentY = y;
     if (!sl.validate(stamp)) {
        stamp = sl.readLock();
        try {
          currentX = x;
          currentY = y;
        } finally {
           sl.unlockRead(stamp);
        }
     }
     return Math.sqrt(currentX * currentX + currentY * currentY);
   }

   void moveIfAtOrigin(double newX, double newY) { // upgrade
     // Could instead start with optimistic, not read mode
     long stamp = sl.readLock();
     try {
       while (x == 0.0 && y == 0.0) {
         long ws = sl.tryConvertToWriteLock(stamp);
         if (ws != 0L) {
           stamp = ws;
           x = newX;
           y = newY;
           break;
         }
         else {
           sl.unlockRead(stamp);
           stamp = sl.writeLock();
         }
       }
     } finally {
       sl.unlock(stamp);
     }
   }
 }

并且可以从不同的线程调用类Point的所有方法:

为什么我们不需要字段x和y被声明为易失性?

是否保证执行Point#moveIfAtOrigin方法的代码在获取StampedLock#readLock后始终会看到对x和y字段的最新更改?

当我们调用StampedLock#writeLockStampedLock#readLock时,是否建立了某种记忆屏障?

有人能引用有关这方面的文件吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-30 09:21:20

我不知道为什么没有在文档中明确引用它--可能是因为它是隐含的,但在内部,它会将Unsafe.compareAndSwapLong转换为LOCK CMPXCHG,在x86上有full memory barrier (我假设类似的事情是在其他平台上完成的);因此,它们实际上不需要是volatile

实际上,x86上任何有lock的指令都会有一个完整的内存屏障。

票数 2
EN

Stack Overflow用户

发布于 2017-08-30 09:34:37

Lock接口的Javadoc声明如下:

存储器同步 所有锁实现都必须强制执行内置监视器锁提供的相同的内存同步语义,如Java语言规范(17.4内存模型)所述: 成功的锁操作与成功的锁定操作具有相同的内存同步效果。成功的解锁操作与成功的解锁操作具有相同的内存同步效果。不成功的锁定和解锁操作以及重入锁定/解锁操作不需要任何内存同步效果。

尽管StampedLock没有实现Lock,但它有一个类似于asReadLock()的方法:

返回此StampedLock的普通锁视图,其中Lock.lock()方法映射到readLock(),其他方法也是如此。

它返回StampedLock的内部类ReadLockView的一个实例,这是Lock的一个实际实现。

但是,由于它只是一个委托者,这意味着原始方法必须创建内存屏障,以遵守Lock接口的内存同步强制执行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45956249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档