最终使用关键字防止JVM重新订购是一个好/正确的做法



我只是想到了这个问题,我还没有在任何地方提出类似的问题。如果我没有找到副本,我可以关闭这一内容。这是一个简单的例子:

假设这是一个多线程方案,在作者线程中,我想保证我首先写入值A,然后将值B写入数据结构。

  public void writeMethod(...) {
     try {
        writeValueA(...);
     } finally {
        writeValueB(...);
     }
  }

我知道finally对于例外处理很有用,对于清理资源很常见。但是我的问题是,使用finally关键字作为防止JVM重新排序我的代码/说明的明确方法是一个好/正确的做法吗?

方法

public void writeMethod(…) {
    try {
       writeValueA(…);
    } finally {
       writeValueB(…);
    }
}

在语义上等同于

public void writeMethod(…) {
    try {
       writeValueA(…);
    } catch(Throwable t) {
       writeValueB(…);
       throw t;
    }
    writeValueB(…);
}

所做的一切,确保writeValueB(…);如果writeValueA(…);抛出异常,也将执行CC_3。如果没有异常,那么普通的

没有区别
writeValueA(…);
writeValueB(…);

最值得注意的是,它对Java内存模型没有任何其他语义。通常,没有办法在不补充读者方面的努力的情况下实施线程对共享数据的安全修改。

如果我正确理解您的目的,请在写线程中使用finally来确保

  • 如果读取线程可以读取更新的 B,则必须对此读取线程进行更新。

这无法通过finally关键字来实现。即使写线程编写AB,JVM也无法Gurantee读取线程也可以更新A,即使它可以更新B而无需同步。

相关内容

最新更新