10

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

4

4 回答 4

8

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

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

于 2009-06-08T21:39:27.360 回答
7

我不知道为什么 volatile 不能应用于 C# 中的 64 位整数,但是您可以使用Thread.VolatileWrite在 C# 中做您想做的事情。volatile 关键字只是此调用的语法糖。

摘抄:

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

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

于 2009-06-08T21:59:40.500 回答
5

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

于 2009-06-08T21:36:28.833 回答
0

我猜 C# 中的 long 不能是 volatile 的,因为它们大于 32 位并且不能在原子操作中访问。即使它们不会存储在寄存器或 CPU 缓存中,因为读取或写入值需要多个操作,所以一个线程可能读取该值,而另一个线程正在写入它。

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

于 2009-06-08T21:38:06.300 回答