java - 如何知道显式锁是否已成功提供内存可见性?

标签 java multithreading concurrency

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

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. 其他线程获取锁,然后循环...

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

最佳答案

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

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

关于您的缓存问题:CPU 不仅仅决定刷新缓存。缓存会保留在原位,直到被覆盖。

关于java - 如何知道显式锁是否已成功提供内存可见性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12436153/

相关文章:

java泛型和继承问题

java - Stax 是否有标准 API,以便我可以更换库来查看最快的库?

javascript - 我正在尝试创建一台使用机器人类来玩卡住标签的计算机

java - 如何更新集合中另一个集合内的元素?

c# - 将 .NET 4 线程转换为 .NET 2

java - Java中两个线程之间的时间延迟

scala - 奇怪的行为 : Scala Actors 2. 7.7 与 2.8-快照

java - Spring 原型(prototype)引用 Singleton

java - ExecutorCompletionService 和 FixThreadPool 执行器之间的区别

sql-server - 使用UPDLOCK和READPAST选择top 1对整个表设置排他锁