Java 似乎支持 long 类型的 volatile 字段,而 C# 不支持 - 这背后的原因是什么?

发布于 2024-07-23 08:59:32 字数 30 浏览 8 评论 0原文

谁能向我解释这两种不同方法的优点和缺点是什么?

Can anyone explain to me what the benefits and and drawbacks of the two different approaches are?

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

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

发布评论

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

评论(4

迷你仙 2024-07-30 08:59:32

当Java中的doublelong易失性时,Java 语言规范的§17.7 要求以原子方式读取和写入它们。 当它们不是易失性时,可以在多次操作中写入它们。 例如,这可能会导致 long 的高 32 位包含新值,而低 32 位仍包含旧值。

原子读写更容易让程序员推理并编写正确的代码。 然而,在某些环境中,对原子操作的支持可能会给 VM 实现者带来负担。

When a double or long in Java is volatile, §17.7 of the Java Language Specification requires that they are read and written atomically. When they are not volatile, they can be written in multiple operations. This can result, for example, in the upper 32 bits of a long containing a new value, while the lower 32 bits still contain the old value.

Atomic reads and writes are easier for a programmer to reason about and write correct code with. However, support for atomic operations might impose a burden on VM implementers in some environments.

装迷糊 2024-07-30 08:59:32

我不知道为什么 volatile 不能应用于 C# 中的 64 位整数,但您可以使用 Thread.VolatileWrite 在 C# 中执行您想要的操作。
易失性关键字只是此调用的语法糖。

摘抄:

注意:
在 C# 中,在字段上使用 volatile 修饰符可保证对该字段的所有访问
使用 Thread.VolatileRead 或 Thread.VolatileWrite。

语法糖(关键字)适用于 32 位整数,但您可以在 64 位整数上使用实际的方法调用。

I don't know the reason why volatile cannot be applied to 64-bit ints in C#, but You can use Thread.VolatileWrite to do what you want in C#.
The volatile keyword is just syntactic sugar on this call.

excerpt:

Note:
In C#, using the volatile modifier on a field guarantees that all access to that field
uses Thread.VolatileRead or Thread.VolatileWrite.

The syntactic sugar (keyword) applies to 32-bit ints, but you can use the actual method calls on 64-bit ints.

呆头 2024-07-30 08:59:32

我想这取决于内存模型可以保证什么。 我对 CLI 内存模型(C# 必须使用的)了解不多,但我知道它会保证 32 位...但不是 64 位(尽管它会保证 x64 上的 64 位引用 -完整规则位于 ECMA 334v4) 的 §17.4.3 中。 所以它不可能是易失性。 不过,您仍然拥有 Interlocked 方法(例如 long Interlocked.Exchange(ref long,long)long Interlocked.Increment(ref long) > 等)。

I guess it comes down to what the memory model can guarantee. I don't know a vast amount about the CLI memory model (that C# has to use), but I know it'll guarantee 32 bits... but not 64 (although it'll guarantee a 64-bit reference on x64 - the full rules are in §17.4.3 of ECMA 334v4) . So it can't be volatile. You still have the Interlocked methods, though (such as long Interlocked.Exchange(ref long,long) and long Interlocked.Increment(ref long) etc).

成熟稳重的好男人 2024-07-30 08:59:32

我猜测 long 在 C# 中不能是易失性的,因为它们大于 32 位并且无法在原子操作中访问。 尽管它们不会存储在寄存器或 CPU 缓存中,但由于读取或写入该值需要多个操作,因此一个线程可能会读取该值,而另一个线程正在写入该值。

我相信Java实现易失性字段的方式和DotNet的方式之间存在差异,但我不确定细节。 Java 可能会在字段上使用锁来防止 C# 存在的问题。

I'm guessing that longs can't be volatile in C# because they are larger than 32-bits and can not be accessed in an atomic operation. Even though they would not be stored in a register or CPU cache, because it takes more than one operation to read or write the value it is possible for one thread to read the value while another is in the process of writing it.

I believe that there is a difference between how Java implements volatile fields and how DotNet does, but I'm not sure on the details. Java might use a lock on the field to prevent the problem that C# has.

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