我正在阅读tips and tricks文章,我想我会尝试一些以前从未做过的C#内容。因此,下面的代码没有实际用途,但仅仅是一个'测试函数'来看看会发生什么。C#ThreadStatic + volatile成员不按预期方式工作
无论如何,我有两个静态私有字段:
private static volatile string staticVolatileTestString = "";
[ThreadStatic]
private static int threadInt = 0;
正如你所看到的,我测试ThreadStaticAttribute和挥发性关键字。
无论如何,我有一个测试方法,看起来像这样:
private static string TestThreadStatic() {
// Firstly I'm creating 10 threads (DEFAULT_TEST_SIZE is 10) and starting them all with an anonymous method
List<Thread> startedThreads = new List<Thread>();
for (int i = 0; i < DEFAULT_TEST_SIZE; ++i) {
Thread t = new Thread(delegate(object o) {
// The anon method sets a newValue for threadInt and prints the new value to the volatile test string, then waits between 1 and 10 seconds, then prints the value for threadInt to the volatile test string again to confirm that no other thread has changed it
int newVal = randomNumberGenerator.Next(10, 100);
staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " setting threadInt to " + newVal;
threadInt = newVal;
Thread.Sleep(randomNumberGenerator.Next(1000, 10000));
staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " finished: " + threadInt;
});
t.Start(i);
startedThreads.Add(t);
}
foreach (Thread th in startedThreads) th.Join();
return staticVolatileTestString;
}
我希望看到从该函数返回的是一个像这样的输出:
thread 0 setting threadInt to 88
thread 1 setting threadInt to 97
thread 2 setting threadInt to 11
thread 3 setting threadInt to 84
thread 4 setting threadInt to 67
thread 5 setting threadInt to 46
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88
然而,是什么我得到的是这样的:
thread 0 setting threadInt to 88
thread 4 setting threadInt to 67
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88
第二个“一半”的输出是预期的(我想这意味着th在ThreadStatic领域工作就像我想的那样),但是似乎有些初始输出已经从第一个'half'中“跳过”了。
此外,第一个'half'中的线程出现故障,但我知道一旦您调用Start(),线程就不会立即运行;而是内部操作系统控制器会根据它认为合适的方式启动线程。
编辑:没有他们没有,其实,我只是以为他们是因为我的大脑错过了连续数
所以,我的问题是:什么错误导致我失去的几行第一个'一半'的输出?例如,线'线程3设置threadInt到84'在哪里?
我运行你的代码几次,总是得到预期的输出... –
我想下注的地方,对字符串+ =的调用是在上一个线程设置它之前获取值,新线程将用新值覆盖它(因此线程1已将其输出跳过)。 – Charleh
@DannyChen我在一个四核上,这不是在应用程序中运行的唯一代码;不知道这两者是否有意义。如果你愿意,我可以上传整个代码(只有两个.cs文件)。 – Xenoprimate