![](/img/trans.png)
[英]Why does declaring a combination of bit fields inside an enum produce a different result than declaring it outside of the enum?
[英]Why does using volatile produce a different result?
private const int Total = 500000;
private static volatile int _count = 0;
private static void Main()
{
Task task = Task.Factory.StartNew(Decrement);
for (int i = 0; i < Total; i++)
{
_count++;
}
task.Wait();
Console.WriteLine(_count);
Console.ReadLine();
}
private static void Decrement()
{
for (int i = 0; i < Total; i++)
{
_count--;
}
}
有時結果為0,有時結果為-xxxxxx。 我不知道為什么。 任何人都可以解釋它並告訴我正確的用法。
volatile
保證不重新排序操作並禁用緩存優化,但不保證線程安全 - 所以你可以得到0到-Total
任何結果(如果每對--
和++
正確混合)。 我已經介紹了“preper mixing”以回答為什么下面的C#多線程代碼雖然在調試器中沒有輸出零但是? 。
當你期望別人修改值時, volatile
是有用的,所以你的代碼總是讀取合理的最近值,這也是一致的(即對於++你不會得到由0xffff的高部分和(0xffff + 1)的低部分組成的int
) - 你會得到一個或另一個)因為volatile只適用於原子寫入的類型。
如果要在2個線程中修改計數器 - 請使用Interlocked.Increment
/ Interlocked.Decrement
。
如Alexei Levenkov所說, volatile
不保證線程安全。 您可以使用System.Threading.Interlocked
。
在此之后,您的示例將如下所示:
private const int Total = 500000;
private static volatile int _count = 0;
private static void Main()
{
Task task = Task.Factory.StartNew(Decrement);
for (int i = 0; i < Total; i++)
{
System.Threading.Interlocked.Increment(ref _count);
}
task.Wait();
Console.WriteLine(_count);
Console.ReadLine();
}
private static void Decrement()
{
for (int i = 0; i < Total; i++)
{
System.Threading.Interlocked.Decrement(ref _count);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.