在大多数计算机上,增加变量操作不是一个原子操作,需要执行下列步骤:
1、将实例变量中的值加载到寄存器中。
2、增加或减少该值。
3、在实例变量中存储该值。(来自MSDN)
.net中的System.Threading命名空间的Interlocked类保证了变量以一个原子操作的方式操作。
经验显示,那些需要在多线程下被保护的资源通常是整型的,而这些被共享的整型值最常见的操作就是增加、减少。Interlocked类提供了一个专门的机制用于完成这些特定的操作。
下面的例子是一个没有使用Interlocked类的操作:
class Program
{
static long counter = 1;
static void Main(string[] args)
{
System.Threading.Thread t1 = new System.Threading.Thread(f1);
System.Threading.Thread t2 = new System.Threading.Thread(f2);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
System.Console.Read();
}
static void f1)
{
for (int i = 1; i <= 1000; i++)
{
counter++;
System.Console.WriteLine("Counter++ {0}", counter);
System.Threading.Thread.Sleep(10);
}
}
static void f2)
{
for (int i = 1; i <= 1000; i++)
{
counter--;
System.Console.WriteLine("Counter++ {0}", counter);
System.Threading.Thread.Sleep(10);
}
}
}
最后的结果counter的值为2,如果我们是用单线程操作的话counter的值应该是1,下面的例子是使用Interlocked类的:
class Program
{
static long counter = 1;
static void Main(string[] args)
{
System.Threading.Thread t1 = new System.Threading.Thread(f1);
System.Threading.Thread t2 = new System.Threading.Thread(f2);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
System.Console.Read();
}
static void f1()
{
for (int i = 1; i <= 5; i++)
{
Interlocked.Increment(ref counter);
System.Console.WriteLine("Counter++ {0}", counter);
System.Threading.Thread.Sleep(10);
}
}
static void f2()
{
for (int i = 1; i <= 5; i++)
{
Interlocked.Decrement(ref counter);
System.Console.WriteLine("Counter++ {0}", counter);
System.Threading.Thread.Sleep(10);
}
}
}
这次最后的结果是1。
本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/528799
,如需转载请自行联系原作者