我可以想到一些使用DateTime对象是原子的非常有用的用例。从语言设计的角度来看,有什么优势可以使DateTime不稳定?
答案 0 :(得分:5)
volatile
关键字不保证原子性。 Atomicity is guaranteed for all data types of 32-bits or fewer,有或没有关键字。
volatile
关键字的目的是确保所有线程都在查看变量的同一副本。您可能会惊讶地发现可能存在多个副本:它们可以保存在主内存中,如您所料,但也可以保存在一个或多个级别的CPU高速缓存中或CPU寄存器中。
当您使用volatile
关键字时,编译器将发出一些额外的指令(“memory barriers”)并跳过某些优化以确保所有线程都能看到变量的相同副本。就是这样。
对于大于32位的类型,无论如何都需要lock
,锁定automatically put those memory barriers in place。那些变量不需要那么不稳定;围绕使用lock
访问变量的代码。
答案 1 :(得分:0)
volatile
关键字只能应用于原子可更新的字段,例如int, long 引用类型等。(更多信息请参见docs)。
获得所需行为的一种方法是lock statements。这将确保一次只有一个线程可以进入"锁定"代码部分(也称为批判部分)。
答案 2 :(得分:-2)
有许多编译器和JiT编译器优化。例如,如果你写:
{
int temp = Int32.Parse(input);
Console.WriteLine(temp);
}
JiT可能会在调试版本之外思考:“嘿,int变量实际上并没有在其他地方使用过。我可以像这样编译它”:
Console.WriteLine(Int32.Parse(input));
它会有完全相同的结果。“
当人们有这样的嵌套调用时,我经常会尝试使用临时变量将它们分开,充分了解JiT可以(并且可能会)处理它们。此更改不会产生相关的性能影响,但会提高可读性和可调试性。
编译器也可以采用相反的方式。例如,如果您两次调用相同的索引,它实际上会尝试通过添加一个临时变量来保存索引绑定检查。当您期望获得新值时,您可能实际上正在使用本地副本。
但是对于多任务处理和多线程处理,任何此类Optimsiation可能会给您带来大量额外的麻烦。 volatile会关闭那些优化。但它只能这样做,如果类型有优化开始。