最近在学java,学到多线程时发现重排序的特性,想看看C#会不会重排序。然后就求证了一下。嗨!发现了个大宝藏哎。
废话不多说,咱直接上代码
internal class Program
{
private static void Main(string[] args)
{
new Program().loopCal();
Console.Read();
}
private int x = 0, y = 0;
private int a = 0, b = 0;
/// <summary>
/// 测试指令重排问题
///
/// 测试结果:.net 未解决这个问题
///
/// 测试版本:.net Framework 2.0 和 .net Framework 4.7.2
/// </summary>
private void loopCal()
{
int i = 0;
while (true)
{
i++;
x = 0; y = 0;
a = 0; b = 0;
Thread t1 = new Thread(() =>
{
a = 1;
x = b;
});
Thread t2 = new Thread(() =>
{
b = 2;
y = a;
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
//x,y??
if (x == 0 & y == 0)
{
Console.WriteLine($"第{i}次执行,验证了cpu指令重排,x=0,y=0 ");
break;
}
}
}
}
执行结果:
看到这个执行结果我就不乐意了,为什么才几百次就报出来。难道C#不如Java吗?
以下是Java的执行结果:
然后想想看网上能不能搜出解决办法,因为java有解决办法,C#也有解决办法。然后就搜到了这个帖子 看的不是很明白的帖子
看到这段话
然后就修改了一下代码试了一下。
internal class Program
{
private static void Main(string[] args)
{
new Program().loopCal();
Console.Read();
}
public int x { get; set; }
public int y { get; set; }
public int a { get; set; }
public int b { get; set; }
/// <summary>
/// 测试指令重排问题
///
/// 测试结果:.net 未解决这个问题
///
/// 测试版本:.net Framework 2.0 和 .net Framework 4.7.2
/// </summary>
private void loopCal()
{
int i = 0;
while (true)
{
i++;
x = 0; y = 0;
a = 0; b = 0;
Thread t1 = new Thread(() =>
{
a = 1;
x = b;
});
Thread t2 = new Thread(() =>
{
b = 2;
y = a;
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
//x,y??
if (x == 0 & y == 0)
{
Console.WriteLine($"第{i}次执行,验证了cpu指令重排,x=0,y=0 ");
break;
}
}
}
}
然后听了大概十来分钟的风扇的声音。程序依然执行。我心想这个冲排序的问题应该解决了啊。
PS:之前工作中遇到了很诡异的问题,代码怎么看都没有问题,就是在服务器上过上一段时间就有问题了,还在公司里还原不出来,并且重启一下就好了,很可能就是重排序导致的。