【发布时间】:2018-03-05 02:44:41
【问题描述】:
我对成员变量和静态变量进行了快速测试,我发现了一个有趣的结果,如果一个变量是静态对象的成员变量,即使在线程竞赛上下文中也总是正确计算,但如果是变量静态变量,它会遇到问题。
class Program
{
static void Main(string[] args)
{
var locker = new object();
ThreadPool.SetMaxThreads(64, 64);
var numOfThreads = 64;
WaitHandle[] waitHandles = new WaitHandle[numOfThreads];
var sw = new Stopwatch();
sw.Start();
for (long i = 0; i < numOfThreads; i++)
{
var handle = new EventWaitHandle(false, EventResetMode.ManualReset);
waitHandles[i] = handle;
ThreadPool.QueueUserWorkItem((state) =>
{
obj.run();
((EventWaitHandle)handle).Set();
}, handle);
//obj.run();
}
WaitHandle.WaitAll(waitHandles);
sw.Stop();
Console.WriteLine($"Exit Performance test {sw.ElapsedMilliseconds} output: {obj.x}");
Console.ReadKey();
}
static MyClass obj = new MyClass();
}
class MyClass
{
private object locker = new object();
//public static int x = 0;
public int x = 0;
public void run() {
//lock (locker)
{
for (int j = 0; j < 10000000; j++)
{
x = x + 1;
}
Console.WriteLine($"id: {Thread.CurrentThread.ManagedThreadId}, count of loop: {x}");
}
var f = 0;
Console.WriteLine($"id: {Thread.CurrentThread.ManagedThreadId}, $$start: {f}");
for (int j = 0; j < 10000000; j++)
{
f = f + 1;
}
Console.WriteLine($"id: {Thread.CurrentThread.ManagedThreadId}, $$end: {f}");
}
}
据我了解,静态对象及其成员字段在多线程共享的内存中具有 1 个实例副本,因此它应该与使用静态变量相同,但不知何故它的行为有所不同。
问题: 1. 多线程中的静态字段和成员字段有什么区别? 2.这是否意味着静态字段比成员字段运行得更快?
谢谢!
【问题讨论】:
-
在这种情况下,您可以使用 Interlocked.Increment。对于更复杂的类型,使用锁或其他一些线程同步方式来避免多个线程并行处理共享资源。
-
请不要发布代码截图 - 发布代码本身。
-
@Evk 我一定会做到的
-
我尝试运行您的代码,无论
x是否为静态,我都有相同的行为。您确定在使用静态成员进行测试时没有取消注释lock (locker)语句吗?
标签: c# multithreading