使用Interlocked的意外结果

Clo*_*ock 0 .net c# multithreading

我有这个代码

int j = -1;
Parallel.For(0, 100, i =>
{
    Console.Write("i= " +i);
    Interlocked.Increment(ref j);
    Console.Write(" j= " + j);
    Console.WriteLine();
});
Run Code Online (Sandbox Code Playgroud)

在运行之后,我希望以i某种方式随机显示值,而不是按升序排列,但是对于j变量的值,我希望它们始终按升序排列.

所以现在我在某个时候有这个输出:

在此输入图像描述

所以有一个j= 78值之间9394,这是正确的?难道一些请你解释我为什么在这里,而不是之间有这样的价值7779,这是因为Console.Write方法不是线程安全的?

j给出的变量值(正如我所期望的那样)是否按升序排列,输出j = 78只是Console.Write方法的一个小故障,因为它不是线程安全的?

Ser*_*rvy 6

对于"j"变量的值,我期望它们一直以升序排列.

它不仅不能保证,甚至不能保证每个数字只打印一次.它可以多次打印一个数字,或者根本不打印.一个线程可以递增数字(假设从0到1),然后暂停,让另一个线程运行,然后再次递增数字(到2),打印它,然后暂停,让第一个线程恢复,然后打印再次使用相同的值(在这种情况下为2).

同样,一个线程可以将变量解析为一个值,然后暂停,让另一个线程增加它几十次,然后打印它,然后让原始线程恢复,在所有这些之前打印从变量中提取的值很久增量.

从根本上说,变量的增量和值的打印不是原子操作.您需要显式同步该代码块,以防止多个线程同时处于这两个操作的中间,以便获得您正在描述的行为.