Interlocked. increment method: Make ++ an atomic operation; interlocked. decrement method makes -- an atomic operation.
What is an atomic operation. That is, it will not be interrupted by others, because a statement in C # will become multiple statements after being compiled into machine code.
In a multi-threaded environment, thread switching may occur among the multiple statements. Interlocked. Increment and interlocked. decrement can be used to avoid interruption and ensure thread safety.
Example of msnd using interlocked. increment method and interlocked. decrement method:
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}" +
"\ NSAID fecountinstances: {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; // do not use atomic operations
Static int safeinstancecount = 0; // use atomic operations
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 );
}
}
Example of atomic operation not required
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 ++;
}
}
Result:
/*
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 192361
Sums = 175155
Sums = 200000
Sums = 176024
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 200000
Sums = 176322
*/
Why is the sum 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.
That is to say, because a statement in C # will become multiple statements after compiled into machine code, and the thread is insecure, 100th operations of sum ++ will be interrupted, however, after 200,000th ++ operations, the CPU only polls the 100th operations of sum ++. At this time, the sum value is 101,
From: http://www.cnblogs.com/cappuccino/archive/2011/01/06/1927659.html