Multithreading

General Questions

It’s a feature of modern operating systems with which we can run multiple programs at same time example Word,Excel etc.

Multithreading forms subset of multitasking instead of having to switch between programs this feature switches between different parts of the same program. Example you are writing in word and at the same time word is doing a spell check in background.

A thread is an independent stream of instructions within a program's context.
It is the basic unit to which the operating system allocates processor time.
A thread has a priority and every thread has its own stack, but the memory for the program code and heap are shared among all threads of a single process.

One or more threads run in an AppDomain. An AppDomain is a runtime representation of a logical process within a physical process. Each AppDomain is started with a single thread, but can create additional threads from any of its threads. Note: All threading classes are defined in System.Threading namespace.

System.Threading has all the classes related to implement threading. Any .NET application who wants to implement threading has to import this namespace. Note: .NET program always has at least two threads running one the main program and second the garbage collector.

Thread priority can be changed by using
Threadname.Priority = ThreadPriority.Highest
Following are different levels of Priority provided by .NET:

  • ThreadPriority.Highest
  • ThreadPriority.AboveNormal
  • ThreadPriority.Normal
  • ThreadPriority.BelowNormal
  • ThreadPriority.Lowest

"Thread.CurrentThread" refers to the current thread running in the method."CurrentThread" is a public static property.

Thread's execution can be paused by calling the Thread.Sleep method. This method takes an integer milliseconds value that determines how long the thread should sleep. Example Thread.CurrentThread.Sleep(2000).

You can also place a thread into the sleep state for an indeterminate amount of time by calling
Thread.Sleep(System.Threading.Timeout.Infinite)
To interrupt this sleep you can call the
Thread.Interrupt method.

It is Similar to Sleep and Interrupt. Suspend allows you to block a thread until another thread calls Thread.Resume.
The difference between Sleep and Suspend is that the latter does not immediately place a thread in the wait state. The thread does not suspend until the .NET runtime determines that it is in a safe place to suspend it. Sleep will immediately place a thread in a wait state.

Thread.Abort() stops the thread execution at that moment itself.

There are two versions of Thread.Join:

  • Thread.Join()
  • Thread.Join(int millisecondsTimeout )
  • Thread.Join(TimeSpan)

The Thread.Join method is useful for determining if a thread has completed before starting another task. The Join method waits a specified amount of time for a thread to end. If the thread ends before the time-out, Join returns True; otherwise it returns False. Once we call Join the calling procedure stops and waits for the thread to signal that it is done.
For example we have "Thread1" and "Thread2" and while executing 'Thread1" we call Thread2.Join(). So "Thread1" will wait until "Thread2" has completed its execution.
Thread.Join(Integer) and Thread.Join(TimeSpan) ensures that threads do not wait for a long time. If it exceeds a specific time which is provided in integer the waiting thread will start.

Daemon thread's run in background and stop automatically when nothing is running program. Example of a Daemon thread is "Garbage collector". Garbage collector runs until some .NET code is running or else its idle.
We can make a thread Daemon by setting Thread.Isbackground = true.
When we create a thread with the Thread class, we can define it as being either a foreground or background thread by setting the property IsBackground.

We need to be careful with when using threads. If two threads (e.g. the main and any worker threads) try to access the same variable at the same time, we'll have a problem. This can be very difficult to debug because they may not always do it at exactly the same time. To avoid the problem, we can lock a variable before accessing it. However, if two threads lock the same variable at the same time, we'll have a deadlock problem.
Lock statement acquires an exclusive lock for a statement block before executing the block.
lock (x)
{
// Some code...
}
where x is an expression of a reference type.

Yes we can use events with threads, this is one of the technique to synchronize one thread with other.

ThreadState property can be used to get detail of a thread. Thread can have one or combination of statuses. System.Threading.ThreadState enumeration has all the values to detect a state of thread. Some sample states are IsRunning, IsAlive, Suspended etc.

Interlock class provides atomic operations for variables that are shared by multiple threads.
It has methods by which we can achieve the following functionalities:

  • Increment Values
  • Decrement values
  • Exchange values between variables
  • Compare values from any thread in a synchronization mode

Example:
System.Threading.Interlocked.Increment(IntA)

Monitor objects are used to ensure that a block of code runs without being interrupted by code running on other threads. In other words, code in other threads cannot run until code in the synchronized code block has finished.
lock statement is provided in order to simplify access to Monitor object.
The lock statement is resolved by the compiler to the use of the Monitor class. The Monitor class is almost similar to a lock but its advantage is better control than the lock statement. We can instruct the lock's enter and exit explicitly.

Threads that call one of the wait methods of a synchronization event must wait until another thread signals the event by calling the Set method. There are two synchronization event classes. Threads set the status of ManualResetEvent instances to signaled using the Set method. Threads set the status of ManualResetEvent instances to nonsignaled using the Reset method or when control returns to a waiting WaitOne call. Instances of the AutoResetEvent class can also be set to signaled using Set, but they automatically return to nonsignaled as soon as a waiting thread is notified that the event became signaled.

Twist: - What is a mutex object?
Wait handles sends signals of a thread status from one thread to other thread. There are three kind of wait modes:

  • WaitOne
  • WaitAny
  • WaitAll

When a thread wants to release a Wait handle it can call Set method. We can use Mutex (mutually exclusive) objects for the following modes. Mutex objects are synchronization objects that can only be owned by a single thread at a time. Threads request ownership of the Mutex object when they require exclusive access to a resource. Because only one thread can own a Mutex object at any time, other threads must wait for ownership of a Mutex object before using the resource.
The WaitOne method causes a calling thread to wait for ownership of a Mutex object. If a thread terminates normally while owning a Mutex object, the state of the Mutex object is set to signaled and the next waiting thread gets ownership.

Mutex offers synchronization across multiple threads. The Mutex class is derived from WaitHandle, we can do a WaitOne() to acquire the mutex lock and be the owner of the mutex that time. The mutex is released by invoking the ReleaseMutex() method.

We may want to lock a resource only when data is being written and permit multiple clients to simultaneously read data when data is not being updated. The ReaderWriterLock class enforces exclusive access to a resource while a thread is modifying the resource, but it allows nonexclusive access when reading the resource. ReaderWriterLock is a useful alternative to exclusive locks that cause other threads to wait, even when those threads do not need to update data.

A good and careful planning can avoid deadlocks. There are many ways to reduce deadlocks. For example Monitor, and Interlocked classes, Wait handles, Event raising from one thread to other thread, ThreadState property which we can poll and act accordingly etc.

A process is a collection of threads that share the same virtual memory. A thread is a path of execution that run on CPU. A process has at least one thread of execution, and a thread always run in a process context.

  1. by implementing Runnable
  2. by extending Thread

The Thread class has constructors that take a ThreadStart delegate or a ParameterizedThreadStart delegate; the delegate wraps the method that is invoked by the new thread when we call the Start method.

  1. IsAlive property
  2. Join()
  3. Resume()
  4. Suspend()
  5. Start()
  6. Sleep()
  7. Abort()

The Join() method

main thread

In order to refer to the current thread in .NET, the Thread.CurrentThread method can be used. It is a public static property.

  1. new
  2. runnable
  3. blocked
  4. dead

System uses synchronization mechanism to make sure that a resource is used by only one thread at a time when more than one thread needs to access a shared resource at the same time. Mutex grants exclusive access to the shared resource to a single thread. A second thread that needs to acquire a particular mutex is suspended until the first thread releases the mutex.

.NET has been designed from the start to support multi-threaded operations. There are two main ways of multi-threading which .NET encourages: starting your own threads with ThreadStart delegates, and using the ThreadPool class either directly (using ThreadPool.QueueUserWorkItem) or indirectly using asynchronous methods (such as Stream.BeginRead, or calling BeginInvoke on any delegate).

In general, we should create a new thread "manually" for long-running tasks, and use the thread pool only for brief jobs. The thread pool can only run so many jobs at once, and some framework classes use it internally, so we don't want to block it with a lot of tasks which need to block for other things.
On the other hand, for short-running tasks, particularly those created often, the thread pool is an excellent choice.

Yes

The thread execution can be paused by invoking the Thread.Sleep(IntegerValue) method where IntegerValue is an integer that determines the milliseconds time frame for which the thread in context has to sleep.

low-priority