Sei sulla pagina 1di 15

Thread Pooling

Thread pooling is the process of creating a collection of threads during the initialization
of a multithreaded application, and then reusing those threads for new tasks as and
when required, instead of creating new threads. Then every process has some fixed
number of threads depending on the amount of memory available, those threads are the
need of the application but we have freedom to increase the number of threads. Every
thread in the pool has a specific given task. The thread returns to the pool and waits for
the next assignment when the given task is completed.

Usually, the thread pool is required when we have number of threads are created to
perform a number of tasks, in this organized in a queue. Typically, we have more tasks
than threads. As soon as a thread completes its task, it will request the next task from
the queue until all tasks have been completed. The thread can then terminate, or sleep
until there are new tasks available.

Creating thread pooling

The .Net framework library included the "System.Threading.ThreadPool" class. it was


so easy to use.You need not create the pool of threads, nor do you have to specify how
many consuming threads you require in the pool. The ThreadPool class handles the
creation of new threads and the distribution of the wares to consume amongst those
threads.

There are a number of ways to create the thread pool:

 Via the Task Parallel Library (from Framework 4.0).

 By calling ThreadPool.QueueUserWorkItem.

 Via asynchronous delegates.


 Via BackgroundWorker.

Entering the Thread Pool via TPL

The task parallel library provide the task class for enter the thread pool easy. The task
class is the part of .Net Framework 4.0 .if you're familiar with the older constructs,
consider the nongeneric Task class a replacement for ThreadPool.QueueUserWorkItem,
and the generic Task<TResult> a replacement for asynchronous delegates. The newer
constructs are faster, more convenient, and more flexible than the old.

To use the nongeneric Task class, call Task.Factory.StartNew, ing in a delegate of the
target method:

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

class Akshay
{
static void Run()
{
Console.WriteLine("Welcome to the C# corner thread pool!");
}
static void Main() // The Task class is in System.Threading.Tasks
{
Task.Factory.StartNew(Run);
Console.Read();
}
}

Output :

C# Multithreading
Multithreading in C# is a process in which multiple threads work simultaneously. It is a
process to achieve multitasking. It saves time because multiple tasks are being executed
at a time. To create multithreaded application in C#, we need to use System.Threding
namespace.

System.Threading Namespace
The System.Threading namespace contains classes and interfaces to provide the facility
of multithreaded programming. It also provides classes to synchronize the thread
resource. A list of commonly used classes are given below:

o Thread
o Mutex
o Timer
o Monitor
o Semaphore
o ThreadLocal
o ThreadPool
o Volatile etc.

The first thread which is created inside a process is called Main thread. It starts first and
ends at last.

Let's see an example of Main thread in C#.

1. using System;
2. using System.Threading;
3. public class ThreadExample
4. {
5. public static void Main(string[] args)
6. {
7. Thread t = Thread.CurrentThread;
8. t.Name = "MainThread";
9. Console.WriteLine(t.Name);
10. }
11. }

Output:

MainThread
The Abort() method is used to terminate the thread. It raises ThreadAbortException if
Abort operation is not done.

1. using System;
2. using System.Threading;
3. public class MyThread
4. {
5. public void Thread1()
6. {
7. for (int i = 0; i < 10; i++)
8. {
9. Console.WriteLine(i);
10. Thread.Sleep(200);
11. }
12. }
13. }
14. public class ThreadExample
15. {
16. public static void Main()
17. {
18. Console.WriteLine("Start of Main");
19. MyThread mt = new MyThread();
20. Thread t1 = new Thread(new ThreadStart(mt.Thread1));
21. Thread t2 = new Thread(new ThreadStart(mt.Thread1));
22.
23. t1.Start();
24. t2.Start();
25. try
26. {
27. t1.Abort();
28. t2.Abort();
29. }
30. catch (ThreadAbortException tae)
31. {
32. Console.WriteLine(tae.ToString());
33. }
34. Console.WriteLine("End of Main");
35. }
36. }

Output:

Output is unpredictable because thread may be in running state.


Start of Main

End of Main

ThreadPriority
1. using System;
2. using System.Threading;
3. public class MyThread
4. {
5. public void Thread1()
6. {
7. Thread t = Thread.CurrentThread;
8. Console.WriteLine(t.Name+" is running");
9. }
10. }
11. public class ThreadExample
12. {
13. public static void Main()
14. {
15. MyThread mt = new MyThread();
16. Thread t1 = new Thread(new ThreadStart(mt.Thread1));
17. Thread t2 = new Thread(new ThreadStart(mt.Thread1));
18. Thread t3 = new Thread(new ThreadStart(mt.Thread1));
19. t1.Name = "Player1";
20. t2.Name = "Player2";
21. t3.Name = "Player3";
22. t3.Priority = ThreadPriority.Highest;
23. t2.Priority = ThreadPriority.Normal;
24. t1.Priority = ThreadPriority.Lowest;
25.
26. t1.Start();
27. t2.Start();
28. t3.Start();
29. }
30. }

Lifecycle and States of a Thread in C#


A thread in C# at any point of time exists in any one of the following states. A thread lies
only in one of the shown states at any instant:
1. Unstarted
2. Runnable
3. Running
4. Not Runnable
5. Dead
Flow Chart:

1. Unstarted state: When an instance of a Thread class is created, it is in the unstarted


state, means the thread has not yet started to run when the thread is in this state. Or in
other words Start() method is not called.
Thread thr = new Thread();
Here, thr is at unstarted state.
2. Runnable State: A thread that is ready to run is moved to runnable state. In this state,
a thread might actually be running or it might be ready to run at any instant of time. It
is the responsibility of the thread scheduler to give the thread, time to run. Or in other
words, the Start() method is called.
3. Running State: A thread that is running. Or in other words, the thread gets the
processor.
4. Not Runnable State: A thread that is not executable because
 Sleep() method is called.
 Wait() method is called.
 Due to I/O request.
 Suspend() method is called.
5. Dead State: When the thread completes its task, then thread enters into dead,
terminates, abort state.

Implementing Thread States in C#

In C#, to get the current state of the thread, use ThreadState or IsAlive property provided by
the Thread class.
Synatx:
public ThreadState ThreadState{ get; }
OR
public bool IsAlive { get; }
Thread class provides different types of methods to implement the states of the threads.
 method is used to temporarily suspend the current execution of the thread for
Sleep()
specified milliseconds, so that other threads can get the chance to start the execution,
or may get the CPU for execution.
 Join() method is used to make all the calling thread to wait until the main thread, i.e.
joined thread complete its work.
 Abort() method is used to abort the thread.
 Suspend() method is called to suspend the thread.
 Resume() method is called to resume the suspended thread.
 Start() method is used to send a thread into runnable State.
Example:
filter_none
edit
play_arrow
brightness_4

// C# program to illustrate the

// states of the thread

using System;

using System.Threading;

public class MyThread {


// Non-Static method

public void thread()

for (int x = 0; x < 2; x++) {

Console.WriteLine("My Thread");

public class ThreadExample {

// Main method

public static void Main()

{
// Creating instance for

// mythread() method

MyThread obj = new MyThread();

// Creating and initializing

// threads Unstarted state

Thread thr1 = new Thread(new ThreadStart(obj.thread));

Console.WriteLine("ThreadState: {0}",

thr1.ThreadState);

// Running state

thr1.Start();

Console.WriteLine("ThreadState: {0}",

thr1.ThreadState);
// thr1 is in suspended state

thr1.Suspend();

Console.WriteLine("ThreadState: {0}",

thr1.ThreadState);

// thr1 is resume to running state

thr1.Resume();

Console.WriteLine("ThreadState: {0}",

thr1.ThreadState);

Output:
ThreadState: Unstarted
ThreadState: Running
ThreadState: SuspendRequested
ThreadState: Running
My Thread
My Thread

Threading with Monitor


A monitor is a mechanism for ensuring that only one thread at a time may be running a
certain piece of code (critical section). A monitor has a lock, and only one thread at a
time may acquire it. To run in certain blocks of code, a thread must have acquired the
monitor. A monitor is always associated with a specific object and cannot be dissociated
from or replaced within that object.

Monitor has the following features:

 It is associated with an object on demand.


 It is unbound, which means it can be called directly from any context.
 An instance of the Monitor class cannot be created.

The following information is maintained for each synchronized object:

 A reference to the thread that currently holds the lock.


 A reference to a ready queue, which contains the threads that are ready to obtain
the lock.
 A reference to a waiting queue, which contains the threads that are waiting for
notification of a change in the state of the locked object.

Monitor Class

The Monitor Class Provides a mechanism that synchronizes access to objects. The
Monitor class is a collection of static methods that provides access to the monitor
associated with a particular object, which is specified through the method's first
argument. the class provide following method.

 Monitor.Enter() : Acquires an exclusive lock on the specified object. This action


also marks the beginning of a critical section.
 Monitor.Exit() : Releases an exclusive lock on the specified object. This action
also marks the end of a critical section protected by the
locked object.
 Monitor.Pules() : Notifies a thread in the waiting queue of a change in the locked
object's state.
 Monitor.Wait() : Releases the lock on an object and blocks the current thread
until it reacquires the lock.
 Monitor.PulesAll() : Notifies all waiting threads of a change in the object's state.
 Monitor.TryEnter() : Attempts to acquire an exclusive lock on the specified object.

In the following example we have three threads which are trying to write a file
(akshay.txt). Basically each thread will wait until the locker object gets released by the
first thread that achieved a lock, before it attempts to write to our file.

using System;
using System.IO;
using System.Threading;
namespace monitorclass
{
class Program
{
static object locker = new object();
static void ThreadMain()
{
Thread.Sleep(800); // Simulate Some work
WriteToFile(); // Access a shared resource / critical section
}
static void WriteToFile()
{
String ThreadName = Thread.CurrentThread.Name;
Console.WriteLine("{0} using C-sharpcorner.com", ThreadName);
Monitor.Enter(locker);
try

{
using (StreamWriter sw = new StreamWriter(@"D:\akshaydata\akshay.txt",
true))
{
sw.WriteLine(ThreadName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Monitor.Exit(locker);
Console.WriteLine("{0} releasing C-sharpcorner.com", ThreadName);
}
}
static void Main(string[] args)
{
for (int i = 0; i < 3; i++)

{
Thread thread = new Thread(new ThreadStart(ThreadMain));
thread.Name = String.Concat("Thread - ", i);
thread.Start();

}
Console.Read();
}
}
}

Output
C# Thread Synchronization
Synchronization is a technique that allows only one thread to access the resource for the
particular time. No other thread can interrupt until the assigned thread finishes its task.

In multithreading program, threads are allowed to access any resource for the required
execution time. Threads share resources and executes asynchronously. Accessing shared
resources (data) is critical task that sometimes may halt the system. We deal with it by
making threads synchronized.

It is mainly used in case of transactions like deposit, withdraw etc.

Advantage of Thread Synchronization


o Consistency Maintain
o No Thread Interference

C# Lock
We can use C# lock keyword to execute program synchronously. It is used to get lock
for the current thread, execute the task and then release the lock. It ensures that other
thread does not interrupt the execution until the execution finish.

Here, we are creating two examples that executes asynchronously and synchronously.
C# Example: Without Synchronization
In this example, we are not using lock. This example executes asynchronously. In other
words, there is context-switching between the threads.

1. using System;
2. using System.Threading;
3. class Printer
4. {
5. public void PrintTable()
6. {
7. for (int i = 1; i <= 10; i++)
8. {
9. Thread.Sleep(100);
10. Console.WriteLine(i);
11. }
12. }
13. }
14. class Program
15. {
16. public static void Main(string[] args)
17. {
18. Printer p = new Printer();
19. Thread t1 = new Thread(new ThreadStart(p.PrintTable));
20. Thread t2 = new Thread(new ThreadStart(p.PrintTable));
21. t1.Start();
22. t2.Start();
23. }
24. }

C# Thread Synchronization Example


In this example, we are using lock. This example executes synchronously. In other
words, there is no context-switching between the threads. In the output section, we can
see that second thread starts working after first threads finishes its tasks.

1. using System;
2. using System.Threading;
3. class Printer
4. {
5. public void PrintTable()
6. {
7. lock (this)
8. {
9. for (int i = 1; i <= 10; i++)
10. {
11. Thread.Sleep(100);
12. Console.WriteLine(i);
13. }
14. }
15. }
16. }
17. class Program
18. {
19. public static void Main(string[] args)
20. {
21. Printer p = new Printer();
22. Thread t1 = new Thread(new ThreadStart(p.PrintTable));
23. Thread t2 = new Thread(new ThreadStart(p.PrintTable));
24. t1.Start();
25. t2.Start();
26. }
27. }

Potrebbero piacerti anche