Interlocked.Increment 方法 和Interlocked.Decrement 方法作用
来源:互联网 发布:一座城池知乎 编辑:程序博客网 时间:2024/06/07 14:30
Interlocked.Increment 方法:让++成为原子操作;Interlocked.Decrement 方法让--成为原子操作。
什么叫原子操作呢。就是不会被别人打断,因为C#中的一个语句,编译成机器代码后会变成多个语句。
在多线程环境中,线程切换有可能会发生在这多个语句中间。使用Interlocked.Increment,Interlocked.Decrement 可以避免被打断,保证线程安全。
使用Interlocked.Increment 方法和Interlocked.Decrement 方法MSND例子:
using System;using System.Threading;class Test{ static void Main() { Thread thread1 = new Thread(new ThreadStart(ThreadMethod)); Thread thread2 = new Thread(new ThreadStart(ThreadMethod)); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); // Have the garbage collector run the finalizer for each // instance of CountClass and wait for it to finish. GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine("UnsafeInstanceCount: {0}" + "\nSafeCountInstances: {1}", CountClass.UnsafeInstanceCount.ToString(), CountClass.SafeInstanceCount.ToString()); } static void ThreadMethod() { CountClass cClass; // Create 100,000 instances of CountClass. for(int i = 0; i < 100000; i++) { cClass = new CountClass(); } }}class CountClass{ static int unsafeInstanceCount = 0;//不使用原子操作 static int safeInstanceCount = 0;//使用原子操作 static public int UnsafeInstanceCount { get {return unsafeInstanceCount;} } static public int SafeInstanceCount { get {return safeInstanceCount;} } public CountClass() { unsafeInstanceCount++; Interlocked.Increment(ref safeInstanceCount); } ~CountClass() { unsafeInstanceCount--; Interlocked.Decrement(ref safeInstanceCount); }}
不用原子操作例子
class Program { static void Main(string[] args) { for (int loop = 0; loop < 20; loop++) { sum = 0; Thread t1 = new Thread(Thread1); Thread t2 = new Thread(Thread2); t1.Start(); t2.Start(); t1.Join(); t2.Join(); Console.WriteLine("sum = " + sum); // sum = 200000 ? } } static int sum; static void Thread1() { for (int i = 0; i < 100000; i++) sum++; } static void Thread2() { for (int i = 0; i < 100000; i++) sum++; } }
结果:
/*
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 192361
sum = 175155
sum = 200000
sum = 176024
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 176322
*/
Why the sum is not always 200000?
The reason is that sum++ is not thread safe (see the possible problem).
That is the reason we need Interlocked.Increment(), which guarantees the sum is always 200000.
Thread1 (sum++) Thread2 (sum++)
--------------------------------------------------------------------
mov EAX, dword ptr sum .
inc EAX .
. mov EAX, dword ptr sum // load sum into a register
. inc EAX // increase it
. mov dword ptr sum, EAX // save back
mov dword ptr sum, EAX
--------------------------------------------------------------------
problem: two sum++ are called in different thread,
but the sum is incremented only once.
也就是说因为C#中的一个语句,编译成机器代码后会变成多个语句,线程不安全,sum++的第100次操作就被打断了,而在第200000次++操作结束后CPU才轮询到sum++的第100次操作,这时sum的值就是101,
本文转自:http://www.cnblogs.com/cappuccino/archive/2011/01/06/1927659.html
- Interlocked.Increment 方法 和Interlocked.Decrement 方法作用
- .NET多线程同步方法详解(一):自由锁(InterLocked)
- NET多线程同步方法详解(一):自由锁(InterLocked)
- NET多线程同步方法详解(一):自由锁(InterLocked)
- NET多线程同步方法:自由锁(InterLocked)
- Spring Memcached 使用incr 方法报cannot increment or decrement non-numeric value 解决方法
- Interlocked(续)
- Interlocked 类
- InterLocked 锁
- System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)的问题
- .Net Core在X86上实现Interlocked.Increment(ref long)的方式
- Silverlight 2.0使用Lock, Interlocked, EventWaitHandle, Monitor来实现线程同步//C#线程同步的几种方法
- InterLocked的几个函数
- Interlocked系列互锁函数
- Interlocked系列互锁函数
- 黑马程序员--interlocked(互锁)
- Interlocked Variable Access
- 自由锁(InterLocked)
- Android NDK 下编译FDK-AAC解码器
- Android input处理机制(二)改键机制
- SqlServer2008修改编辑前200行
- Oracle密码忘记了怎么修改密码
- 端口映射PortTunnel使用实例_博客起步
- Interlocked.Increment 方法 和Interlocked.Decrement 方法作用
- jquery ajax返回值乱码解决方法
- keepalived+lvs的配置
- Home key点亮屏幕后, 使手机不自动回到 launcher 界面
- 几个常用编码介绍
- PODOFO编译之4——加密测试
- unable to connect to your virtual device genymotion will now stop check your virtualbox network
- hadoop增加和删除节点
- NSLog