为什么我们不需要与StampedLock挥发?

Dmi*_*nov 11 java multithreading volatile memory-barriers java-8

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

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);
     }
   }
 }
Run Code Online (Sandbox Code Playgroud)

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

为什么我们不需要将字段x和y声明为volatile?

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

当我们打电话时StampedLock#writeLock,是否存在任何形式的记忆障碍StampedLock#readLock

任何人都可以指出有关该文档的引用吗?

Eug*_*ene 2

我不知道为什么文档中没有明确引用这一点 - 可能是因为它是隐含的,但在内部会执行 a Unsafe.compareAndSwapLongwhich 翻译为LOCK CMPXCHG, which on x86has full memory barrier(我假设类似的事情是在其他平台上完成的);所以这些没有必要是volatile真的。

x86实际上,任何具有 a 的指令都lock将具有完整的内存屏障。

  • 文档中明确引用了它。 (2认同)