In this post, we will see how to use Lock and Mutex for obtaining a lock in a thread.
We start creating a Console application where, we will add a class called Methods:
[METHODS.CS]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System; using System.Threading; namespace LockAbortThread { public class Methods { public void RunMethods() { Thread firstThread = new Thread(MethodOne); Thread secondThread = new Thread(MethodOne); firstThread.Start(); secondThread.Start(); } private void MethodOne() { for ( int i = 1; i < 6; i++) { Console.WriteLine($ "Output: {i} ---- ThreadId:{Thread.CurrentThread.ManagedThreadId}" ); Thread.Sleep(1000); } } } } |
Then, we modify the Program file in order to run RunMethods():
[PROGRAM.CS]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System; namespace LockAbortThread { internal class Program { static void Main( string [] args) { Console.WriteLine( "Start threads" ); Methods objMethods = new Methods(); objMethods.RunMethods(); } } } |
Now, if we run the application, this will be the result:

In this example, if we would like to run the two Threads in sequence, we could either use the method Join() (we have seen it in the post: Multithreading – Joining Threads) or, we could use the keyword LOCK.
With the keyword LOCK, we are sure that no thread will enter a critical section of code while another thread is in that section:
[METHODS.CS]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using System; using System.Threading; namespace LockAbortThread { public class Methods { public void RunMethods() { Thread firstThread = new Thread(MethodOne); Thread secondThread = new Thread(MethodOne); firstThread.Start(); secondThread.Start(); } private void MethodOne() { lock ( this ) { for ( int i = 1; i < 6; i++) { Console.WriteLine($ "Output: {i} ---- ThreadId:{Thread.CurrentThread.ManagedThreadId}" ); Thread.Sleep(1000); } } } } } |
Now, if we run the application, this will be the result:

LOCK it is used in simple situations because, it doesn’t have any parameters or methods that could help us to resolve for example a deadlock.
A deadlock is a situation where, two or more threads, are frozen in their execution because they are waiting for each other to finish.
In order to avoid a deadlock, we can use Mutex that is synchronization primitive that can also be used for interprocess synchronization.
It works like a Lock because, it acquires an exclusive lock on a shared resource from concurrent access but, it works across multiple processes.
For other information: Microsoft web site.
We can use Mutex is this simple way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using System; using System.Threading; namespace LockAbortThread { public class Methods { private static Mutex mutex = new Mutex(); public void RunMethods() { Thread firstThread = new Thread(MethodOne); Thread secondThread = new Thread(MethodOne); firstThread.Start(); secondThread.Start(); } private void MethodOne() { mutex.WaitOne(); for ( int i = 1; i < 6; i++) { Console.WriteLine($ "Output: {i} ---- ThreadId:{Thread.CurrentThread.ManagedThreadId}" ); Thread.Sleep(1000); } mutex.ReleaseMutex(); } } } |
If we run the application, this will be the result:

We can see that it works fine but, in reality, this implementation has the same problem with the deadlock like a LOCK.
In order to avoid a deadlock with Mutex, we can insert a timeout.
If Mutex doesn’t run after a specific number of seconds, the system will stop the execution of the application, avoiding in this way a deadlock:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | using System; using System.Threading; namespace LockAbortThread { public class Methods { private static Mutex mutex = new Mutex(); public void RunMethods() { Thread firstThread = new Thread(MethodOne); Thread secondThread = new Thread(MethodOne); firstThread.Start(); secondThread.Start(); } private void MethodOne() { // the value is in Milliseconds // if after 6 seconds, the thread cannot run, it will stop to run if (mutex.WaitOne(6000)) { for ( int i = 1; i < 6; i++) { Console.WriteLine($ "Output: {i} ---- ThreadId:{Thread.CurrentThread.ManagedThreadId}" ); Thread.Sleep(1000); } mutex.ReleaseMutex(); } else { // System is busy and application cannot run the Thread Console.WriteLine( "Application can run a Thread. The system is busy." ); } } } } |
If we run the application, this will be the result:

But now, if we set the Timeout to 5 seconds, we will see that the application will stop after the first thread because it tooks more of 5 seconds to complete the first method:
1 2 3 4 5 6 7 8 9 10 11 12 | private void MethodOne() { // the value is in Milliseconds // if after 5 seconds, the thread cannot run, it will stop to run if (mutex.WaitOne(5000)) { for ( int i = 1; i < 6; i++) { . .. ... } |
If we run the application, this will be the result:
