Definition
We can define Thread as a small set of executable instructions and this set of instructions can be used to isolate a task from a process. To obtain parallelism and give interactive user interaction to the application one of the most efficient way is to implement multiple threads. Tasks and Threads are related with each other. A Task is something that we want to do and a Thread is one of the possible workers that perform the Task. Threads are often known as lightweight processes. Dot Net framework has thread-associate classes in System.Threading namespace.
Creating a Thread
We have to create a call back function first which will be a starting point for our new Thread. The block of code below illustrates the example of a simple Thread.
- class Program
- {
- //Call back function for Thread
- public static void MyCallBackFunction()
- {
- int i = 0;
- while (i < 4)
- {
- Console.WriteLine("Hello new Thread..");
- i++;
- }
- }
- static void Main(string[] args)
- {
- //Create an object for the Thread
- Thread myThread = new Thread(new ThreadStart(MyCallBackFunction));
- //To start a Thread
- myThread.Start();
- //To abort a Thraed throwing the ThreadAbortException
- //myThread.Abort();
- //To suspant a Thread
- //myThread.Suspend();
- //To resume a Thread
- //myThread.Resume();
- Console.ReadKey();
- }
- }
Hello new Thread..
Hello new Thread..
Hello new Thread..
Hello new Thread..
Interaction between Threads
After starting a Thread we don't have to stop or free the Thread. This is done automatically by the .NET framework common language runtime. The example below demonstrate how to interact between two threads running simultaneously within the same process. The program execution begins by creating an object of class ThreadDemo that reference the Demo() method. The IsAlive property allows the program to wait until the thread is initialized and the Sleep() method tells the thread to give up its time slice and also stop executing for a certain user define period measured in milliseconds. After that the Thread is stopped and joined. The functionality of joining a thread is to make the main thread wait for it to die or for a specified time to expire.
- public class ThreadDemo
- {
- public void Demo()
- {
- while (true)
- {
- Console.WriteLine("ThreadDemo.Demo is running under own thread..");
- }
- }
- };
- class Program
- {
- public static int Main()
- {
- Console.WriteLine("Example of Thread Start, Stop and Join..");
- ThreadDemo oAlpha = new ThreadDemo();
- // Create the thread object and passing this object in ThreadDemo.Demo method
- // throughout a ThreadStart delegate. It does not start the thread.
- Thread oThread = new Thread(new ThreadStart(oAlpha.Demo));
- oThread.Start();
- // Spin for a moment waiting for the started thread to become
- // The Thread will be Alive:
- while (!oThread.IsAlive);
- // Main thread is keeping to sleep for 1 millisecond to allow oThread
- // in order to executre some work
- Thread.Sleep(1);
- oThread.Abort();
- // In this point Wait until oThread is finished. Join also has overloads
- // that take a millisecond interval.
- oThread.Join();
- Console.WriteLine();
- Console.WriteLine("ThreadDemo.Demo has finished..");
- try
- {
- Console.WriteLine("Trying to restart ThreadDemo.Demo..");
- oThread.Start();
- } catch (ThreadStateException)
- {
- Console.Write("ThreadStateException restarting ThreadDemo.Demo..");
- Console.WriteLine("Expected aborted! threads cannot be restarted..");
- }
- Console.ReadKey();
- return 0;
- }
- }
Thread Start/Stop/Join Sample
ThreadDemo.Demo is running under own thread..
ThreadDemo.Demo is running under own thread..
ThreadDemo.Demo is running under own thread..
...
...
ThreadDemo.Demo has finished..
Trying to restart ThreadDemo.Demo thread..
ThreadStateException restarting ThreadDemo.Demo..
Expected aborted! threads cannot be restarted..
Nonblocking Synchronization- Full Fence
Full memory barrier (full fence) is the simplest kind of memory barrier. It prevents instruction reordering or caching around that fence calling Thread.MemoryBarrier.
Application of full fences-
- class Question
- {
- int answer;
- bool complete;
- void APart()
- {
- answer = 10;
- // Thread Barrier 1
- Thread.MemoryBarrier();
- complete = true;
- // Thread Barrier 2
- Thread.MemoryBarrier();
- }
- void BPart()
- {
- // Thread Barrier 3
- Thread.MemoryBarrier();
- if (complete)
- {
- // Thread Barrier 4
- Thread.MemoryBarrier();
- Console.WriteLine(answer);
- }
- }
- }
Every individual read or write does not require a full fence and for the three answer field also, the example above would need four fences.
- class Question
- {
- int answer1, answer2, answer3;
- bool complete;
- void APart()
- {
- answer1 = 10;
- answer2 = 15;
- answer3 = 20;
- // Thread Barrier 1
- Thread.MemoryBarrier();
- complete = true;
- // Thread Barrier 2
- Thread.MemoryBarrier();
- }
- void BPart()
- {
- // Thread Barrier 3
- Thread.MemoryBarrier();
- if (complete)
- {
- // Thread Barrier 4
- Thread.MemoryBarrier();
- Console.WriteLine(answer1 + answer2 + answer3);
- }
- }
- }
Another advanced way to solve this problem is to use the volatile keyword to the _complete field.
volatile bool _complete;
The compiler gets instruction from the volatile keyword in order to generate an acquire fence on every read and a release fence on every write. Application of volatile does not prevent a write followed by a read from being swapped.
For example, if Method1 and Method2 simultaneously run on different threads then for a and b both end up with a value of 0.
- class Volatility
- {
- volatile int p, q;
- // Executed on one thread
- void Method1()
- {
- // Volatile write (release-fence)
- p = 1;
- // Volatile read (acquire-fence)
- int a = q;...
- }
- // Executed on another thread
- void Method2()
- {
- // Volatile
- write (release-fence)
- q = 1;
- // Volatile read (acquire-fence)
- int b = p;...
- }
- }
The static VolatileRead() and VolatileWrite() methods in Thread read or write a variable at the time of enforcing generated by the volatile keyword. The implementations of these two methods are relatively inefficient though the way they create full fences.
VolatileWrite method
- public static void VolatileWrite(ref int addr, int val)
- {
- MemoryBarrier();
- addr = val;
- }
- public static int VolatileRead(ref int addr)
- {
- int n = addr; MemoryBarrier(); return n;
- }

Tanvir RahmanPosted Dec 17, 2015, 7:46 AM
Very Good. Thanks for sharing. Go ahead.
Humayun Kabir MamunPosted Sep 15, 2015, 3:00 AM
Nice...
Gopal C. BalaPosted Sep 14, 2015, 5:28 AM
Thank you
Akash MalhotraPosted Sep 12, 2015, 5:02 PM
Nice article
Santhakumar MunuswamyPosted Sep 12, 2015, 3:15 AM
Thanks for nice article:)
Shakti SaxenaPosted Sep 11, 2015, 8:39 AM
Informative...Good Article. Add a bit about Locking mechanism "Thread Safety" to enjoy the completeness of Threading framework in C#.
RakeshPosted Sep 10, 2015, 9:37 AM
Good share buddy
Sibeesh VenuPosted Sep 10, 2015, 8:08 AM
Nice Share
Rajeesh MenothPosted Sep 10, 2015, 6:29 AM
Nice Share