我正在努力理解Varhandles,但有些示例包含了不同的变量可见性方法。
例如
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
class Point {
volatile int x;
private static final VarHandle X;
static {
try {
X = MethodHandles.lookup().
findVarHandle(Point.class, "x",
int.class);
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
// ...
}
示例显示了易失性的x字段。有必要吗?我的意思是,如果你有一个volatile字段,那么我们有一个内存屏障和其他与程序顺序相关的机制等。但从我的角度来看,在这个例子中,volatile是不必要的,否则它会对性能产生重大影响。从另一方面来说,Varhandle提供了所有必要的工具来安全地做到这一点。
什么是正确的解决方案?
这取决于情况。
Varhandle
有getVolatile()
/setVolatile()
可以访问x
,如果它被声明为volatile:
返回变量的值,具有读取的内存语义,就好像变量被声明为
volatile
一样。
但这只会在您通过VarHandle
访问x
时处理这种情况。
如果任何代码直接访问x
,则仍然需要将其声明为易失性,因为否则JIT仍然可以将x
缓存在内部寄存器中并只读取一次-例如,在以下代码中:
while (x < 10) {
// do something with x
}
从性能角度来看,这并不重要——通过VarHandle
访问x
不会比直接访问x
快。(如果您将x
声明为volatile,但通过不遵守volatile语义的VarHandle
的get()
方法访问它,可能会出现异常,但随后会遇到并发问题。(