getVolatile 和 getAcquire 有什么区别?

adr*_*rhc 9 java jls

使用例如AtomicIntegergetVolatile时与getAcquire有什么区别?

\n\n

PS:这些都与

\n\n
\n

a\xc2\xa0synchronizes-with\xc2\xa0edge 的源称为\xc2\xa0release,目标称为\xc2\xa0acquire。

\n
\n\n

来自https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.3

\n

Ali*_*ouk 8

这一切都回到了我们想要如何优化代码的问题。重新排序代码方面的优化。编译器可能会重新排序以进行优化。getAquire确保它后面的指令不会在它之前执行。这些指令可能会重新排序,但它们始终会在getAquire.

这与setRelease(for VarHandle) where结合使用setRelease,确保在它之前发生的事情不会被重新排序为在它之后发生。

例子:

Thread1:

    var x = 1;
    var y = 2;
    var z = 3;

    A.setRelease(this, 10)
Run Code Online (Sandbox Code Playgroud)

x、y 和 z 的分配将在 A.setRelease 之前发生,但可能会自行重新排序。

Thread 2:

if (A.getAquire(this) == 10) {
  // we know that x is 1, y is 2 and z = 3
}
Run Code Online (Sandbox Code Playgroud)

这是并发程序的一个很好的用例,您不必在所有内容上增加波动性,而只需要在另一个指令之前执行一些指令。

对于getVolatile,该变量的处理方式与 Java 中的任何 volatile 变量一样。没有发生重新排序或优化。

这个视频很适合理解所谓的“内存排序模式”,即简单、不透明、释放/获取和易失性。