假设一个类有一个public int counter由多个线程访问的字段.这int只是递增或递减.
要增加此字段,应使用哪种方法,为什么?
lock(this.locker) this.counter++;,Interlocked.Increment(ref this.counter);,counter为public volatile.现在,我发现volatile,我已经删除了许多lock语句和使用Interlocked.但是有理由不这样做吗?
我想编写一个程序,它可以直观地说明volatile关键字的行为.理想情况下,它应该是一个程序,它执行对非易失性静态字段的并发访问,并因此而获得不正确的行为.
在同一程序中添加volatile关键字应该可以解决问题.
那是我无法实现的.即使尝试多次,启用优化等,我总是会在没有'volatile'关键字的情况下获得正确的行为.
你对这个话题有什么看法吗?你知道如何在一个简单的演示应用程序中模拟这样的问题吗?它取决于硬件吗?
以下代码
using System.Threading;
class Test
{
volatile int counter = 0;
public void Increment()
{
Interlocked.Increment(ref counter);
}
}
Run Code Online (Sandbox Code Playgroud)
引发以下编译器警告:
"A reference to a volatile field will not be treated as volatile"
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么来提出这个警告?为什么编译器会对此发出警告?
public void MyTest()
{
bool eventFinished = false;
myEventRaiser.OnEvent += delegate { doStuff(); eventFinished = true; };
myEventRaiser.RaiseEventInSeperateThread()
while(!eventFinished) Thread.Sleep(1);
Assert.That(stuff);
}
Run Code Online (Sandbox Code Playgroud)
为什么eventFinished不能变得不稳定并且重要吗?
在我看来,在这种情况下,编译器或运行时可能会变得聪明,并且在while循环中"知道"eventFinished只能为false.特别是当您考虑提升变量作为类的成员生成的方式以及委托作为同一类的方法时,从而剥夺了eventFinished曾经是局部变量这一事实的优化.