.NET Threading Interview Questions Series – Part 1

Q 1.  What is the difference between Process and Thread?

A process is started when you start an Application. A process is a collection of resources like virtual address space, code, security contexts etc. A process can start multiple threads. Every process is start with a single thread called primary thread. You can create n number of threads in a process. Threads share the resources allocated to process.

A process is the parent and threads are his children.

Q 2. Why we need Multi-threading in our project?

Multi-threading is running the multiple threads simultaneously. Some main advantages are:

  • You can do multiple tasks simultaneously. For e.g. saving the details of user to a file while at the same time retrieving something from a web service.
  • Threads are much lightweight than process. They don’t get their own resources. They used the resources allocated to a process.
  • Context-switch between threads takes less time than process.

Q 3. How to start a Thread in C#?

We have to use the Thread class provided by System.Threading namespace. In the constructor of the class, we have to pass the method name which we want to run in separate thread. After than we have to call the start method of Thread class. Below is the example.

using System;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread th = new Thread(ThreadMethod);
            th.Start();
        }

        private static void ThreadMethod()
        {
            Console.WriteLine("Another Thread");
        }
    }
}

Q 4. How to pass parameter in Thread?

In the constructor of Thread, we can pass the method name which accepts only a single parameter. Then we have to pass parameter into the Start method. Below is the example.

static void Main(string[] args)
{
	Thread th = new Thread(ThreadMethod);
	th.Start("Hello");
}

private static void ThreadMethod(object args)
{
	Console.WriteLine(args.ToString());
}

Q 5. What is Thread-Safety? Are .NET framework library methods thread-safe?

A code is called thread-safe if multiple threads can safely manipulate the shared data. In thread-safe code, a thread can not modify the shared data at the same time when other thread is updating the data.

In .NET framework library all static methods are thread-safe and all the instance methods are not thread-safe.

Q 6. What is Race condition?

A race condition happens when two or more threads want to update shared data at the same time.

Q 7. What is volatile keyword?
Volatile is used for serializing the access of variable without using the synchronization primitives. You can use volatile with below types:

  1. References types
  2. Pointer types
  3. Values types
  4. IntPtr

public volatile int number;

Q 8. How can you share data between multiple threads?
There are two ways to share data between multiple threads:

  1. Concurrent collection classes
  2. Using Synchronization Primitives

Q 9. What are Concurrent Collection Classes?
.NET framework class library comes with Concurrent collection classes so that multiple threads can share collection data between them without using synchronization primitives.

There are four types of Concurrent classes.

  1. ConcurrentQueue
  2. ConcurrentStack
  3. ConcurrentDictionary
  4. ConcurrentBag

Q 10. What is synchronization and why it is important?
We use multiple threads to improve the performance of our application. When multiple threads shares data between there is a chance of data corruption. When one thread is writing to the variable another thread is reading the same variable at the same time there is a chance of reading corrupt data.

To stop the dirty reads we use synchronization primitives.

Q 11. Can you count some names of Synchronization primitives?

  1. Monitor
  2. Mutex
  3. SpinLock
  4. ReaderWriterLock
  5. Semaphore
  6. AutoResetEvent
  7. ManualResetEvent
  8. InterLocked
  9. CountDownEvent
  10. Barrier

Q 12. What is Deadlock?

A deadlock is a situation in which two or more processes cannot complete their work. They are blocked and each thread waiting for other threads to release resource they want.

For example, you have two threads T1 and T2 and you have two resources R1 and R2. Both threads want to work with both resources. But in opposite fashion, T1 want to work with R1 first and then with R2. T2 want to work with R2 first and then with R1.

Both threads starts at the same time. T1 locked R1 while at the same time T2 locked R2. Now T1 want a lock on R2 which is already locked by T2 and T2 want a lock on R1 which is already locked by T1. Both threads waiting for other threads to unlock the resources. Both threads are waiting for infinite time and cann’t continue forever.

Q 13. What are four necessary conditions for Deadlock?

  1. Mutual Exclusion: Resources involved must be unshareable between multiple threads.
  2. Hold and Wait: Threads hold the resources they have allocated and waiting for the resources they want.
  3. No pre-emption: If thread lock the resource, other threads cannot take the resource until the thread release it.
  4. Circular Wait: A circular chain must exist in which each thread waiting for other threads to release resources.

Q 14. What is LiveLock?

A livelock is very similar to deadlock except involved threads states are continually changing their state but still they cannot complete their work.

A real-world example of livelock occurs when two people meet in a narrow corridor, and each tries to be polite by moving aside to let the other pass, but they end up swaying from side to side without making any progress because they both repeatedly move the same way at the same time.

Q 15. Suppose one thread has odd numbers like 1,3,5 and other thread has even numbers 2,4,6. How can you synchronize between them and print the numbers in order?

We have to take two AutoResetEvents which each signal each other after they print one number. Below is the full code.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static AutoResetEvent auto1 = new AutoResetEvent(false);
        static AutoResetEvent auto2 = new AutoResetEvent(false);

        static void Main(string[] args)
        {

            var t1 = Task.Factory.StartNew(() => PrintOddNumbers());
            var t2 = Task.Factory.StartNew(() => PrintEvenNumbers());

            Task.WaitAny(t1, t2);

            Console.WriteLine("End");
            Console.ReadLine();
        }

        static void PrintOddNumbers()
        {
            int[] arr = new int[] { 1, 3, 5, 7, 9, 11, 13, 15 };

            foreach (var item in arr)
            {
                Console.WriteLine(item);
                auto2.Set();
                auto1.WaitOne();
            }
        }

        static void PrintEvenNumbers()
        {
            int[] arr = new int[] { 2, 4, 6, 8, 10, 12, 14 };

            foreach (var item in arr)
            {
                auto2.WaitOne();
                Console.WriteLine(item);
                auto1.Set();
            }
            auto1.Set();
        }
    }
}

Q 16. What is immutable object?

An immutable object is an object which states cannot be changed after creation. Immutable objects are useful in concurrent programming as they are thread-safe.

“String” objects are examples of immutable object because we can cannot change the value of string after it is created. Below is the code in which we try to change the second index char of string which gives us error.

string str = "Hello";

str[0] = 'm'; //Doesn't work; Property or indexer 'string.this[int]' cannot be assigned to --it is read only

Q 17. Whey are the keywords necessary for supporting immutable object?

There are two keywords provided by CLR.

  1. const
  2. readonly

Q 18. Can you write the code for immutable object?

static void Main(string[] args)
{
            Person p1 = new Person(1, "Name 1");
}

public class Person
{
	private readonly int id;
        private readonly string name;

        public Person(int id, string name)
        {
            this.id = id;
            this.name = name;
	}
}

Q 19. What is AutoResetEvent?

AutoResetEvent is a synchronization mechanism which work on a bool variable. If the bool variable is false then thread is blocked. If the bool variable is true then thread is unblocked.

AutoResetEvent contains two main methods:

  1. WaitOne() : Blocks the current thread
  2. Set() : Unblock the current thread
  3. Reset() : Sets the state of the event to non-signaled.

Q 20. Write a simple program using AutoResetEvent.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static AutoResetEvent autoEvent = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            Task.Factory.StartNew(() =>
            {
                CalculateSum(50);
            });

            Thread.Sleep(3000);
            autoEvent.Set();

            Console.ReadLine();
        }

        public static void CalculateSum(int maxNumber)
        {
            int sum = 0;
            for (int i = 0; i <= maxNumber; ++i)
            {
                sum += i;
            }
            Console.WriteLine("Sum Calculated. Waiting for Main thread to send signal to unblock me");
            autoEvent.WaitOne();

            Console.WriteLine("Sum: " + sum);
        }
    }
}