2. • A multithreaded program contains two or
more parts that can run concurrently.
• Each part of such a program is called a
thread, and each thread defines a separate
path of execution.
• Thus, multithreading is a specialized form of
multitasking.
• Threads improve performance.
3. • The advantage of threading is the ability to
create applications that use more than one
thread of execution.
• For example, a process can have a user
interface thread that manages interactions
with the user and worker threads that
perform other tasks while the user interface
thread waits for user input.
• They are handled in the .NET Framework with
classes from the base class library.
4. Multithreading
• There are two distinct types of multitasking:
process-based and thread-based.
• A process is a program that is executing.
• Thus, process-based multitasking is the
feature that allows your computer to run two
or more programs concurrently.
• In process-based multitasking, a program is the
smallest unit of code that can be dispatched by
the scheduler.
5. • A thread is a dispatchable unit of executable code.
• In a thread-based multitasking environment, all
processes have at least one thread, but they can
have more.
• This means that a single program can perform two
or more tasks at once.
• Process-based multitasking handles the concurrent
execution of programs.
• Thread-based multitasking deals with the
concurrent execution of pieces of the same
program.
6. • The principal advantage of multithreading is that
it enables you to write very efficient programs
because it lets you utilize the idle time that is
present in most programs.
• A thread can be in one of several states. In
general terms, it can be running.
• It can be ready to run as soon as it gets CPU
time.
• A running thread can be suspended, which is a
temporary halt to its execution.
• It can later be resumed.
• A thread can be blocked when waiting for a
resource. A thread can be terminated, in which
case its execution ends and cannot be resumed.
7. • The .NET Framework defines two types of
threads: foreground and background.
• By default, when you create a thread, it is a
foreground thread, but you can change it to a
background thread.
• The only difference between foreground and
background threads is that a background
thread will be automatically terminated when
all foreground threads in its process have
stopped.
8. • C# and the .NET Framework support both
process-based and thread-based multitasking.
• Thus, you can create and manage both
processes and threads.
• The classes that support multithreaded
programming are defined in the
System.Threading namespace.
• using System.Threading;
9. The Thread Class
• The multithreading system is built upon the
Thread class, which encapsulates a thread of
execution.
• The Thread class is sealed , which means that
it cannot be inherited.
• Thread defines several methods and
properties that help manage threads.
10. Creating and Starting a Thread
• To create a thread, instantiate an object of type
Thread, which is a class defined in
System.Threading.
• The simplest Thread constructor is shown here:
public Thread(ThreadStart entryPoint)
• Here, entryPoint is the name of the method that
will be called to begin execution of the thread.
• ThreadStart is a delegate defined by the .NET
Framework as shown here:
public delegate void ThreadStart( )
11. • Thus, your entry point method must have a
void return type and take no arguments.
• the new thread will not start running until you
call its Start( ) method, which is defined by
Thread.
• The Start( ) method has two forms. One is
public void Start( )
13. // Entry point of thread.
public void Run() {
Console.WriteLine(TN + " starting.");
do {
Thread.Sleep(500);
Console.WriteLine("In " + TN +Count+", Count is " +
Count);
Count++;
} while(Count < 10);
Console.WriteLine(TN + " terminating.");
}
}
14. class MultiThread {
static void Main() {
Console.WriteLine("Main thread starting.")
MyThread mt = new MyThread("Emp #");
// construct a thread from that object.
Thread newThrd = new Thread(mt.Run);
// Finally, start execution of the thread.
newThrd.Start();
Console.WriteLine("Main thread ending.");
}}}
15.
16. • Example:
This program creates two
instances of the Thread and uses the
ThreadStart class to specify their target
methods A and B.
• The threads are started and then they are
joined.
17. using System.Threading;
class Program
{
static void Main()
{
Thread thread1 = new Thread(new ThreadStart(A));
Thread thread2 = new Thread(new ThreadStart(B));
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
}
19. • ThreadStart: You can start threads by passing an
instance of the ThreadStart type in the C#
language.
• Join: When you join a thread, the current thread
stops and waits for the target thread to exit. You
can use Join to ensure all threads are completed
at a certain point in your program.
• Sleep: By using the Sleep method, you can pause
a thread and not have it incur any actual CPU
usage. Instead, the thread is simply delayed for a
certain amount of time, measured in
milliseconds.
20. Some Simple Improvements
using System.Threading;
class MyThread {
public int Count;
public Thread Thrd;
public MyThread(string name) {
Count = 0;
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd.Start();
}
23. Creating Multiple Threads
using System;
using System.Threading;
class MyThread {
public int Count;
public Thread Thrd;
public MyThread(string name) {
Count = 0;
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd.Start();
}
24. // Entry point of thread.
void Run() {
Console.WriteLine(Thrd.Name + " starting.");
do {
Thread.Sleep(500);
Console.WriteLine("In " + Thrd.Name +", Count is “ +
Count);
Count++;
} while(Count < 10);
Console.WriteLine(Thrd.Name + " terminating.");
}
}
25. class MoreThreads {
static void Main() {
Console.WriteLine("Main thread starting.");
// Construct three threads.
MyThread mt1 = new MyThread("Child #1");
MyThread mt2 = new MyThread("Child #2");
MyThread mt3 = new MyThread("Child #3");
Console.WriteLine("Main thread ending.");
}}
26.
27. Determining When a Thread End
• IsAlive: Thread provides two means by which
you can determine whether a thread has
ended.
• First, you can interrogate the read-only IsAlive
property for the thread.
• It is defined like this:
public bool IsAlive { get; }
• IsAlive returns true if the thread upon which it
is called is still running. It returns false
otherwise.
28. class MoreThreads {
static void Main() {
Console.WriteLine("Main thread starting.")
// Construct three threads.
MyThread mt1 = new MyThread("Child #1");
MyThread mt2 = new MyThread("Child #2");
MyThread mt3 = new MyThread("Child #3");
do {
Console.Write(".");
Thread.Sleep(100);
} while (mt1.Thrd.IsAlive && mt2.Thrd.IsAlive &&
mt3.Thrd.IsAlive);
Console.WriteLine("Main thread ending.");
}}
29. Join
• Another way to wait for a thread to finish is to
call Join( ) .
• Its simplest form is shown here:
• public void Join( )
• Join( ) waits until the thread on which it is
called terminates.
• Its name comes from the concept of the
calling thread waiting until the specified
thread joins it.
30. static void Main() {
Console.WriteLine("Main thread starting.");
// Construct three threads.
MyThread mt1 = new MyThread("Child #1");
MyThread mt2 = new MyThread("Child #2");
MyThread mt3 = new MyThread("Child #3");
mt1.Thrd.Join();
Console.WriteLine("Child #1 joined.");
mt2.Thrd.Join();
Console.WriteLine("Child #2 joined.");
32. Thread Priorities
• ThreadPriority defines the following five
priority settings:
ThreadPriority.Highest
ThreadPriority.AboveNormal
ThreadPriority.Normal
ThreadPriority.BelowNormal
ThreadPriority.Lowest
• The default priority setting for a thread is
ThreadPriority.Normal.
33. • To understand how priorities affect thread
execution, we will use an example that
executes two threads, one having a higher
priority than the other.
• The threads are created as instances of the
MyThread class.
• The Run( ) method contains a loop that
counts the number of iterations.
34. •
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
class MyThread {
public int Count;
public Thread Thrd;
static bool stop = false;
static string currentName;
/* Construct a new thread. Notice that this
constructor does not actually start the
threads running. */
public MyThread(string name) {
Count = 0;
Thrd = new Thread(this.Run);
Thrd.Name = name;
currentName = name;
}
// Begin execution of new thread.
void Run() {
Console.WriteLine(Thrd.Name + " starting.");
do {
Count++;
if(currentName != Thrd.Name) {
currentName = Thrd.Name;
Console.WriteLine("In " + currentName);
}
} while(stop == false && Count < 1000);
stop = true;
Console.WriteLine(Thrd.Name + " terminating.");
}}
35. class PriorityDemo {
static void Main() {
MyThread mt1 = new MyThread("High Priority");
MyThread mt2 = new MyThread("Low Priority");
// Set the priorities.
mt1.Thrd.Priority = ThreadPriority.Highest;
mt2.Thrd.Priority = ThreadPriority.BelowNormal;
mt1.Thrd.Start();
mt2.Thrd.Start();
mt1.Thrd.Join();
mt2.Thrd.Join();
Console.WriteLine(mt1.Thrd.Name + " thread counted to " + mt1.Count);
Console.WriteLine(mt2.Thrd.Name + " thread counted to " + mt2.Count);
}}
36. the high-priority thread got approximately 98 percent of the CPU
time. Of course, the precise output you see may vary, depending
on the speed of your CPU and the number of other tasks
running on the system. Which version of Windows you are
running will also have an effect.
37. Synchronization
• When using multiple threads, you will sometimes
need to coordinate the activities of two or more
of the threads.
• The process by which this is achieved is called
synchronization.
• The most common reason for using
synchronization is when two or more threads need
access to a shared resource that can be used by
only one thread at a time.
• For example, when one thread is writing to a file,
a second thread must be prevented from doing so
at the same time.
38. • The key to synchronization is the concept of a
lock, which controls access to a block of code
within an object.
• When an object is locked by one thread, no
other thread can gain access to the locked
block of code.
• When the thread releases the lock, the object
is available for use by another thread.
• Synchronization is supported by the keyword
lock .
39. • The general form of lock is shown here:
lock(lockObj) {
// statements to be synchronized
}
• lockObj is a reference to the object being
synchronized.
• If you want to synchronize only a single
statement, the curly braces are not needed.
40. • A key point to understand about lock is that
the lock-on object should not be publically
accessible. Why?
• Because it is possible that another piece of
code that is outside your control could lock on
the object and never release it.
41. class Program
{
static readonly object objectRef = new object();
static readonly object objectRef1 = new object();
public void A1()
{
lock (objectRef1)
{
//Thread.Sleep(100);
Console.WriteLine(Environment.UserName);
}
}
42. static void A()
{
lock (objectRef)
{
//Thread.Sleep(100);
Console.WriteLine(Environment.SystemDirectory);
}
}
static void Main()
{
Program ob = new Program();
43. for (int i = 0; i < 10; i++)
{
//ThreadStart start = new ThreadStart(A);
// new Thread(start).Start();
Thread th1 = new Thread(new ThreadStart (A));
th1.Start();
}
for (int i = 0; i < 10; i++)
{
// ThreadStart start1 = new ThreadStart(A1);
//new Thread(start1).Start();
Thread th2 = new Thread(ob.A1);
th2.Start();
}
} }
44.
45. 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.
46. • 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.
47.
48. object Class
• C# defines one special class called object that
is an implicit base class of all other classes
and for all other types (including the value
types).
• In other words, all other types are derived
from object .
• This means that a reference variable of type
object can refer to an object of any other
type.
49.
50. • feature added to the .NET Framework by version
4.0 is the Task Parallel Library (TPL). This library
enhances multithreaded programming in two
important ways.
• First, it simplifies the creation and use of multiple
threads.
• Second, it automatically makes use of multiple
processors.
• Another parallel programming feature added by
.NET 4.0 is PLINQ, which stands for Parallel
Language Integrated Query. PLINQ enables you
to write queries that automatically make use of
multiple processors and parallelism when
appropriate.