Tutorial in Using C# For Handling Monitoring Process in Threads
Tutorial in Using C# For Handling Monitoring Process in Threads
Copied from :
http://www.cs.ubbcluj.ro/~vcioban/Bistrita/Manuale/Thinking.in.Csharp.pdf
refCount++; refCount--; } } public static void Main() { for (int i = 0; i < 2; i++) new RefCount1(); } }
The Run( ) method, which is used by a bunch of threads, increments and then decrements refCount, while a thread running the static delegate method ValCheck( ) stops the program if the value of refCount is ever not 0. When you run this, it is not long before refCount becomes either 2 or -1. This is what happens: 1. A RefCount instance thread increments refCount, making it 1. 2. That thread is interrupted by another thread, which increments refCount to 2. 3. The ValCheck( ) thread interrupts that thread and sees a value of 2. To synchronize access to the static value-type refCount, you have to wrap all access to the refCount object inside lock blocks that use some dummy object to synchronize on. You cannot lock (refCount) because its a value type. And lock (this) is ineffective on static objects! So you have to create a static dummy object to serve as a guard for the critical sections:
static SomeObject myDummyObject = new SomeObject(); static void ValCheck() { Console.WriteLine("Starting ValCheck"); while (true) { Console.WriteLine(DateTime.Now); lock(myDummyObject) { if (refCount != 0 && refCount != 1) { Console.WriteLine( "Invalid: " + refCount); return; } } Thread.Sleep(5000); } } void Run() { Console.WriteLine("Starting RefCount"); while (true) { lock(myDummyObject) { refCount++; refCount--; } } }
And indeed, thats the general solution to synchronizing static value types. For the specific problem of reference counting, however, the Interlocked class allows you to increment, decrement, and assign to an int or long in a thread-safe and very, very fast manner. It can also compare two ints or two longs without requiring the overhead of the Monitor implementation. Even aside from its synchronization capabilities, Interlocked should be used to generate serially increasing id values. Although
class StrangeButTrue { static int counter = 0; //Amazingly, this isn't thread-safe
public static int Next() { return counter++; //Chapter 16: Multithreaded Programming 751 } }
is fine for a single-threaded program, its not thread-safe, since the ++ operator reads and assigns the value in two separate operations. A thread can come along after the read but before the assignment and therefore, in a multithreaded program, Next( ) could return the same value twice.