Varhandles,挥发性和内存访问

发布于 2025-01-18 17:29:31 字数 627 浏览 3 评论 0 原文

我试图理解 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 提供了安全执行此操作所需的所有必要仪器。

正确的解决方案是什么?

I am trying to understand Varhandles but some examples contain different approaches to the visibility of a variable.

E.g.

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);
     }
   }
   // ...
}

Example shows x field that is volatile. Is it necessary? I mean if you have a volatile field then we have a memory barrier and other mechanisms related to program order etc. but from my perspective in that example volatile is not necessary otherwise it has a significant impact on performance and from the other side, Varhandle provides all necessary instrumentation to do this safely.

What is the proper solution for that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空心↖ 2025-01-25 17:29:31

这取决于。

VarhandlegetVolatile() / setVolatile() 是如果它声明为 volatile:

返回变量的值,具有读取的内存语义,就好像该变量被声明为易失性

但这仅处理当您通过 VarHandle 访问 x 时的情况。

如果任何代码直接访问x,您仍然需要将其声明为易失性,否则 JIT 仍然允许在内部寄存器中缓存x,并且仅读取一次 - 例如在以下代码中:

while (x < 10) {
    // do something with x
}

从性能角度来看,这并不重要 - 通过 VarHandle 访问 x 不可能比访问 x< 更快/code> 直接。 (如果您将x声明为易失性,但通过不观察易失性的VarHandleget()方法访问它,则可能会出现异常语义 - 但随后你会遇到并发问题。)

It depends.

Varhandle has getVolatile() / setVolatile() that can access x is if it where declared volatile:

Returns the value of a variable, with memory semantics of reading as if the variable was declared volatile.

But that only handles the case when you access x through the VarHandle.

If any code accesses x directly you still need to declare it as volatile because otherwise the JIT is still allowed to cache x in an internal register and read it only once - for example in the following code:

while (x < 10) {
    // do something with x
}

From a performance point this will not matter - accessing x through the VarHandle cannot be faster than accessing x directly. (There might be an exception if you declare x as volatile but access it through the VarHandles get() method that doesn't observe volatile semantics - but then you will run into concurrency issues.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文