【问题标题】:How to know whether an explicit lock has successfully provided memory visibility?如何知道显式锁是否已成功提供内存可见性?
【发布时间】:2012-09-08 07:19:48
【问题描述】:

这是从互联网某处复制的代码:
这种显式锁定如何工作?

public class Lock {
  private Object lockObj = new Object();
  private Thread owner;
  private int lockCount;

  /**
   * Waits for up to 'maxWait' milliseconds to acquire the lock,
   * and returns true if the lock was acquired.
   **/
  public boolean acquireLock(int maxWait) throws InterruptedException {
    Thread currentThread = Thread.currentThread();
    synchronized (lockObj) {
      if (owner == currentThread) {
        lockCount++;
        return true;
      }
      long waitedSoFar = 0L;
      while (owner != null) {
        long t0 = System.currentTimeMillis();
        long timeToWait = maxWait - waitedSoFar;
        if (timeToWait <= 0)
          return false;
        lockObj.wait(timeToWait);
        if (owner != null) {
          waitedSoFar += System.currentTimeMillis() - t0;
        }
      }
      owner = currentThread;
      lockCount = 1;
      return true;
    }
  }
  public void releaseLock() {
    Thread currentThread = Thread.currentThread();
    synchronized (lockObj) {
      if (owner == currentThread) {
        lockCount--;
        if (lockCount == 0) {
          owner = null;
          lockObj.notify();
        }
        return;
      } else {
        // Only the owner can release the lock!
        throw new IllegalStateException();
      }
    }
  }
}

我还没有看到任何特殊的代码来保证内存可见性。唯一与并发相关的是“synchronized(lockObj){ ... }”

这是魔法吗?
CPU 在获取一些同步监视器之前是否只是刷新其所有缓存?
还是相反?
CPU在释放一些同步监视器时是否只是刷新其所有缓存?

编辑:
好吧,我还有一些与并发等待/通知有关的其他事情。

考虑一下。这个显式锁是如何工作的?

  1. 获取锁,修改变量(防止其他线程获取),然后释放锁。
  2. 做任何事。
  3. 获取锁,修改变量(允许其他线程获取)。
  4. 其他线程获取锁,然后循环...

happens-before 关系只是在 3 到 4 之间,对吗?
还是在 1 和 3 之间也可以保证发生前的关系?那么 2 是保证内存可见性?

【问题讨论】:

  • 当一个同步方法退出时,它会自动与任何后续对同一对象的同步方法调用建立起之前的关系。这保证了对象状态的更改对所有线程都是可见的。 docs.oracle.com/javase/tutorial/essential/concurrency/…
  • 那发生在两个同步块之间。在显式锁的情况下,在释放锁和获取锁之间。不在获取锁和释放之间。
  • 您对内存可见性有很多疑问,但您似乎不了解java同步的基础知识?我建议先阅读java concurrency,以便您了解基础知识,然后再提出此类问题。

标签: java multithreading concurrency


【解决方案1】:

没有cpu可以获取的同步监视器之类的东西。监视器是在您正在编程的语言(在本例中为 java)的运行时实现的结构。

java 运行时负责此锁定并禁止其他代码进入同步代码块。 cpu 只看到处理它的指令。

关于您的缓存问题:cpu 不只是决定刷新缓存。缓存会一直保留,直到被覆盖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2011-08-10
    • 2010-11-02
    • 1970-01-01
    相关资源
    最近更新 更多