Varhandles,挥发性和内存访问
我试图理解 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 字段是易失性的。有必要吗?我的意思是,如果你有一个易失性字段,那么我们就有一个内存屏障和其他与程序顺序相关的机制等。但从我的角度来看,在该示例中,易失性是不必要的,否则它会对性能产生重大影响,从另一方面来看,Varhandle 提供了安全执行此操作所需的所有必要仪器。
正确的解决方案是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这取决于。
Varhandle
有getVolatile()
/setVolatile()
是如果它声明为 volatile:但这仅处理当您通过
VarHandle
访问x
时的情况。如果任何代码直接访问
x
,您仍然需要将其声明为易失性,否则 JIT 仍然允许在内部寄存器中缓存x
,并且仅读取一次 - 例如在以下代码中:从性能角度来看,这并不重要 - 通过
VarHandle
访问x
不可能比访问x< 更快/code> 直接。 (如果您将
x
声明为易失性,但通过不观察易失性的VarHandle
的get()
方法访问它,则可能会出现异常语义 - 但随后你会遇到并发问题。)It depends.
Varhandle
hasgetVolatile()
/setVolatile()
that can accessx
is if it where declared volatile:But that only handles the case when you access
x
through theVarHandle
.If any code accesses
x
directly you still need to declare it as volatile because otherwise the JIT is still allowed to cachex
in an internal register and read it only once - for example in the following code:From a performance point this will not matter - accessing
x
through theVarHandle
cannot be faster than accessingx
directly. (There might be an exception if you declarex
as volatile but access it through theVarHandle
sget()
method that doesn't observe volatile semantics - but then you will run into concurrency issues.)