Object Oriented Programming Multithreading Dr. Mike Spann

Slides:



Advertisements
Similar presentations
How to Build Multi- threaded Applications in.NET Mazen S. Alzogbi Technology Specialist Microsoft Corporation.
Advertisements

Ade Azurat, Advanced Programming 2004 (Based on LYS Stefanus’s slides) Advanced Programming 2004, Based on LYS Stefanus’s slides Slide 2.1 Multithreading.
Chapter 14 Multithreading Yingcai Xiao. Multithreading is a mechanism for performing two or more tasks concurrently.  In the managed world of the common.
Threads in C# Threads in C#.
Java How to Program, 9/e CET 3640 Professor: Dr. José M. Reyes Álamo © Copyright by Pearson Education, Inc. All Rights Reserved.
CS220 Software Development Lecture: Multi-threading A. O’Riordan, 2009.
 2006 Pearson Education, Inc. All rights reserved Multithreading.
Multithreading in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
Java How to Program, 9/e CET 3640 Professor: Dr. Reyes Álamo © Copyright by Pearson Education, Inc. All Rights Reserved.
Multithreading.
Parallel Processing (CS526) Spring 2012(Week 8).  Thread Status.  Synchronization in Shared Memory Programming(Java threads ) ◦ Locks ◦ Barriars.
EE2E1. JAVA Programming Lecture 8 Multi-threading.
Collage of Information Technology University of Palestine Advanced programming MultiThreading 1.
Overview of Threading with the.NET Framework  Wallace B. McClure  Scalable Development, Inc. Scalable Development, Inc. Building systems today that perform.
University of Sunderland Java Threading, Mutex and Synchronisation Lecture 02 COMM86 Concurrent and Distributed Software Systems.
 2002 Prentice Hall. All rights reserved. 1 Chapter 14 – Multithreading Outline 14.1 Introduction 14.2 Thread States: Life Cycle of a Thread 14.3 Thread.
1 Java Threads Instructor: Mainak Chaudhuri
Multi-Threaded Application CSNB534 Asma Shakil. Overview Software applications employ a strategy called multi- threaded programming to split tasks into.
Today’s Agenda  Quick Review  Finish Java Threads  The CS Problem Advanced Topics in Software Engineering 1.
Dr. R R DOCSIT, Dr BAMU. Basic Java : Multi Threading 2 Objectives of This Session State what is Multithreading. Describe the life cycle of Thread.
111 © 2002, Cisco Systems, Inc. All rights reserved.
Practical OOP using Java Basis Faqueer Tanvir Ahmed, 08 Jan 2012.
Java Threads. What is a Thread? A thread can be loosely defined as a separate stream of execution that takes place simultaneously with and independently.
Threads in Java. Processes and Threads Processes –A process has a self-contained execution environment. –Has complete set of runtime resources including.
C# I 1 CSC 298 Threads. C# I 2 Introducing Threads  A thread is a flow of control within a program  A piece of code that runs on its own. The execution.
1 Web Based Programming Section 8 James King 12 August 2003.
1.NETConcurrent programmingNOEA / PQC 2007 Concurrent programming Threads –Introduction –Synchronization.
EE4E. C++ Programming Lecture 6 Advanced Topics. Contents Introduction Introduction Exception handling in C++ Exception handling in C++  An object oriented.
Multithreading in Java Sameer Singh Chauhan Lecturer, I. T. Dept., SVIT, Vasad.
Introduction to Threads Session 01 Java Simplified / Session 14 / 2 of 28 Objectives Define a thread Define multithreading List benefits of multithreading.
Multithreading in JAVA
Java Thread and Memory Model
Threads Doing Several Things at Once. Threads n What are Threads? n Two Ways to Obtain a New Thread n The Lifecycle of a Thread n Four Kinds of Thread.
Concurrency Control 1 Fall 2014 CS7020: Game Design and Development.
Java 3: Odds & Ends Advanced Programming Techniques.
Multithreaded programming  Java provides built-in support for multithreaded programming. A multithreaded program contains two or more parts that can run.
Multithreading. Multithreaded Programming A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is.
Chapter11 Concurrent. 集美大学 计算机工程学院 Java 程序设计 年 第二版 Concurrent ●Computer users take it for granted that their systems can do more than one thing.
Object Oriented Programming Multithreading Dr. Mike Spann
Threads in Java Threads Introduction: After completing this chapter, you will be able to code your own thread, control them efficiently without.
Thread A thread represents an independent module of an application that can be concurrently execution With other modules of the application. MULTITHREADING.
Internet Computing Module II. Threads – Multithreaded programs, thread Priorities and Thread Synchronization.
1 Java Programming Java Programming II Concurrent Programming: Threads ( I)
Multithreading & Synchronized Algoritma Pemrograman 3 Sistem Komputer – S1 Universitas Gunadarma 1.
Multithreading. Multitasking The multitasking is the ability of single processor to perform more than one operation at the same time Once systems allowed.
Threads b A thread is a flow of control in a program. b The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
1 Threads in Java Jingdi Wang. 2 Introduction A thread is a single sequence of execution within a program Multithreading involves multiple threads of.
CIS NET Applications1 Chapter 8 – Multithreading and Concurrency Management.
Concurrency in Java MD. ANISUR RAHMAN. slide 2 Concurrency  Multiprogramming  Single processor runs several programs at the same time  Each program.
Concurrent Programming in Java Based on Notes by J. Johns (based on Java in a Nutshell, Learning Java) Also Java Tutorial, Concurrent Programming in Java.
Multithreading / Concurrency
Threading Lecture 11 M. Ipalakova.
Multi Threading.
Multithreading.
Multithreaded Programming in Java
Threads Chate Patanothai.
Multithreading.
Java Based Techhnology
Multithreading.
Threading using C# and .Net
Multithreaded Programming
Multithread Programming
Multithreading in java.
Threads and Multithreading
Foundations and Definitions
Multithreading Dr. John P. Abraham.
Visual Programming COMP-315
Lecture 19 Threads CSE /6/2019.
Java Chapter 3 (Estifanos Tilahun Mihret--Tech with Estif)
Presentation transcript:

Object Oriented Programming Multithreading Dr. Mike Spann

Contents Introduction Introduction Creating and executing threads Creating and executing threads Simple example – a counter thread Simple example – a counter thread Thread priority and thread scheduling Thread priority and thread scheduling Thread states Thread states Thread synchronisation Thread synchronisation Multi-threading and GUI’s Multi-threading and GUI’s Summary Summary

Introduction Multi-threading allows program statements to be executed concurrently Multi-threading allows program statements to be executed concurrently  For example, we can create an application that downloads a large multimedia file whilst at the same time it can support other tasks  The CLR automatic garbage collector runs concurrently with the rest of a.NET application The.NET framework provides extensive support for multithreading The.NET framework provides extensive support for multithreading  It is easy to specify that certain sections of code reside in different execution threads

Introduction Its important to understand the difference between multi- tasking (as carried out by an operating system) and multi- threading (as carried out by a single application) Its important to understand the difference between multi- tasking (as carried out by an operating system) and multi- threading (as carried out by a single application) Multi-tasking refers to an operating system running several processes concurrently Multi-tasking refers to an operating system running several processes concurrently  Each process has its own completely independent data  Multi-tasking is difficult to incorporate in application programs requiring system programming primitives A thread is different from a process in that threads share the same data A thread is different from a process in that threads share the same data  Switching between threads involves much less overhead than switching between programs  Sharing data can lead to programming complications (for example in reading/writing databases)

Creating and executing threads A thread can be initiated using the ThreadStart delegate A thread can be initiated using the ThreadStart delegate This delegate object is passed into the constructor of the Thread object This delegate object is passed into the constructor of the Thread object The delegate is initialized with a method which runs in a separate thread The delegate is initialized with a method which runs in a separate thread  In simple use, this method must have no parameters and return void Calling Thread.Start() starts the thread Calling Thread.Start() starts the thread Similar but more flexible than to the Java approach where the code running in a separate thread is always in the run() method Similar but more flexible than to the Java approach where the code running in a separate thread is always in the run() method  Java also requires the use inheritance or interfaces

Creating and executing threads using System; using System.Threading; class ThreadApp { public static void Main(string[] args) { MyClass myObject=new MyClass(); Thread thread=new Thread(new ThreadStart(myObject.myMethod)); thread.Name="thread"; thread.Start(); } class MyClass { public void myMethod() { Thread thisThread=Thread.CurrentThread; Console.WriteLine("Thread " + thisThread.Name + “ running"); }

Creating and executing threads Main() thread new thread Code in myMethod() executed new thread created

Simple example – a counter thread We will create a simple application which creates separate threads to update a count within a graphical window We will create a simple application which creates separate threads to update a count within a graphical window The application will initiate any number of threads from a simple GUI The application will initiate any number of threads from a simple GUI Initially each thread will be given equal scheduling priority Initially each thread will be given equal scheduling priority  We will look thread scheduling and priority later

Simple example – a counter thread Demos\Counter Thread\CounterThread.exe Demos\Counter Thread\CounterThread.exe Demos\Counter Thread\CounterThread.exe Demos\Counter Thread\CounterThread.exe

Simple example – a counter thread Main thread Create counter thread …..

Simple example – a counter thread using System; using System.Windows.Forms; using System.Threading; public partial class CounterThreadApp : Form { private int nThread = 0; public CounterThreadApp() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { CounterForm c = new CounterForm(nThread++); c.Show(); Thread thread = new Thread(new ThreadStart(c.Count)); thread.Start(); }

using System; using System.Threading; using System.Drawing; using System.Windows.Forms; public partial class CounterForm : Form { private int count = 0; private int threadCount; public CounterForm(int tc) { InitializeComponent(); threadCount = tc; } public void Count() { do { count++; Thread.Sleep(10); countLabel.Text = "Count= " + count; if (threadCount == 0) BackColor = Color.Blue; else if (threadCount == 1) BackColor = Color.Yellow; else if (threadCount == 2) BackColor = Color.Red; else BackColor = Color.Green; Invalidate(); } while (true); }

Thread priority and thread scheduling Each thread has a priority which determines how.NET schedules that thread Each thread has a priority which determines how.NET schedules that thread Obviously threads with higher priority will be given more CPU timeslices than lower priority threads Obviously threads with higher priority will be given more CPU timeslices than lower priority threads  The priority can range between ThreadPriority.Lowest to ThreadPriority.Highest (ThreadPriority is an enumeration)  By default each thread is initialized to ThreadPriority.Normal A thread’s priority can be adjusted through the Priority property A thread’s priority can be adjusted through the Priority property

Thread priority and thread scheduling. NET schedules threads of equal priority in a round robin fashion. NET schedules threads of equal priority in a round robin fashion  Each thread is given a CPU timeslice and then pre-empted  Threads of lower priority are only scheduled when higher priority threads have completed or are sleeping or waiting for system resources  The thread priority can be set through the Priority property of the Thread class

Thread priority and thread scheduling Highest Priority AboveNormal Priority Normal Priority BelowNormal Priority Lowest Priority AB C DE F

Thread states At anyone time, a thread can exist in one of a number of states At anyone time, a thread can exist in one of a number of states The thread state affects its scheduling The thread state affects its scheduling It’s important to understand what these states are and how a thread undergoes a transition between the states It’s important to understand what these states are and how a thread undergoes a transition between the states  The full transition diagram is fairly complicated and we only need the basic ideas initially  Initially a thread is in an Unstarted state and calling the thread’s Start() method puts it in the Running state  The newly running thread can then run to completion (alongside the original thread) until it reaches its Stopped state  However, other more complex scenarios are possible

Thread states Unstarted Running Start() WaitSleepJoin StoppedBlocked

Thread states A running thread can also enter the Stopped state if its Abort() method is called A running thread can also enter the Stopped state if its Abort() method is called  This causes an exception to be thrown in the thread which calls the Abort() method Unstarted Running Start() Stopped Completed Abort()

Thread states A thread becomes Blocked if it issues an IO request or an object lock is not available (see later) A thread becomes Blocked if it issues an IO request or an object lock is not available (see later) Unstarted Running Start() Blocked Lock unavailable Issues IO request Lock available IO request completed

Thread states The WaitSleepJoin state can be entered and exited in a number of ways The WaitSleepJoin state can be entered and exited in a number of ways  A thread can calls its Sleep method to put itself to sleep for a number of milliseconds  The thread can call the Monitor object’s Wait() method to suspend its execution  Waiting threads are in a queue to resume execution using the Moniter object’s Pulse() method  Also one thread can call the waiting or sleeping thread’s Interrupt() method causing it to re-enter the Running state

Thread states The Join() method of Thread causes the calling thread to suspend execution until the thread who’s Join() method has been called terminates The Join() method of Thread causes the calling thread to suspend execution until the thread who’s Join() method has been called terminates  It’s a simple method of synchronising the execution of 2 threads  There is also a Join(int t) method whereby the calling thread resumes execution in t milliseconds no matter what  This version is useful in implementing timers

Thread states Main thread Creates thread t Calls t.Join() Main thread suspends execution Thread t terminates Main thread resumes

Thread states Unstarted Running WaitSleepJoin Start() Wait(),Sleep(t) Join(t) Sleep interval expires Pulse(), PulseAll() Interrupt()

Thread states Example 1. Putting a thread to sleep Example 1. Putting a thread to sleep using System; using System.Threading; class SleepTest { static void SayHello() { Console.WriteLine("Hello, "); Thread.Sleep(10000); Console.WriteLine("World"); } static void Main(string[] args) { Thread thread1 = new Thread(new ThreadStart(SayHello)); thread1.Start(); }

Thread states Example 2. Interrupting a sleeping thread Example 2. Interrupting a sleeping thread  Causes an exception to be thrown using System; using System.Threading; class SleepTest { static void SayHello() { Console.WriteLine("Hello, "); try {Thread.Sleep(10000); } catch (ThreadInterruptedException e) {Console.WriteLine("World");} } static void Main(string[] args) { Thread thread1 = new Thread(new ThreadStart(SayHello)); thread1.Start(); thread1.Interrupt(); }

Thread states Demos\Thread States\SleepTest1.exe Demos\Thread States\SleepTest1.exe Demos\Thread States\SleepTest1.exe Demos\Thread States\SleepTest1.exe Demos\Thread States\SleepTest.exe Demos\Thread States\SleepTest.exe Demos\Thread States\SleepTest.exe Demos\Thread States\SleepTest.exe

ThreadStates Example 3. Synchronising 2 threads using Join() Example 3. Synchronising 2 threads using Join() using System; using System.Threading; class JoinTest1 { static int total = 0; static void Adder() { for (int i = 0; i < ; i++) total += i; } static void Main(string[] args) { Thread thread1 = new Thread(new ThreadStart(Adder)); thread1.Start(); thread1.Join(); Console.WriteLine("The total= " + total); }

ThreadStates Without the synchronising Join(), a sum of zero is displayed Without the synchronising Join(), a sum of zero is displayed  The main thread must wait for the adder thread to complete The main thread waits for the adder thread using Join() The main thread waits for the adder thread using Join()  Demos\Thread States\ThreadSynch.exe Demos\Thread States\ThreadSynch.exe Demos\Thread States\ThreadSynch.exe

Thread states Example 4. A watchdog timer using Join() Example 4. A watchdog timer using Join() using System; using System.Threading; class JoinTest { static void SayHello() { Console.WriteLine("Hello, "); Thread.Sleep(15000); // Something goes wrong, here. Console.WriteLine("World"); } static void Main(string[] args) { Thread thread1 = new Thread(new ThreadStart(SayHello)); thread1.Start(); thread1.Join(10000); if ( thread1.IsAlive ) { Console.WriteLine("Thread 1 timed out. I am killing it."); thread1.Abort(); }

Thread states Demos\Thread States\Watchdog.exe Demos\Thread States\Watchdog.exe Demos\Thread States\Watchdog.exe Demos\Thread States\Watchdog.exe

Thread synchronisation Threads need to share access to objects and may update shared objects Threads need to share access to objects and may update shared objects  For example multiple threads may access a database for an online flight booking system  One thread may be updating a database entry whilst another is reading it may lead to problems We can synchronise threads so that they must complete their action before another thread is scheduled We can synchronise threads so that they must complete their action before another thread is scheduled  We do this by giving one thread at a time exclusive access to code that manipulates shared objects

Thread synchronisation Unsynchronised threads Thread 1Thread 2 Update database Read database Pre-empt

Thread synchronisation Synchronised threads Thread 1Thread 2 Update database Read database

Thread synchronisation A thread can lock a shared object so that it has exclusive access to it A thread can lock a shared object so that it has exclusive access to it Class Monitor provides methods for locking objects Class Monitor provides methods for locking objects  Monitor.Enter(anObject) acquires a lock on anObject  All other threads are blocked if they try to access anObject  Monitor.Exit(anObject) releases the lock on anObject  A thread waiting to access anObject is then unblocked

Thread synchronisation C# also provides a lock keyword in front of a piece of code C# also provides a lock keyword in front of a piece of code A thread entering this piece of code will then have exclusive access to shared object anObject A thread entering this piece of code will then have exclusive access to shared object anObject lock(anObject) { // Synchronized code here }

Thread synchronisation Example – A seat reservation system Example – A seat reservation system  Seats for a concert can be reserved through booking agents  The processing for each booking agent runs in a separate thread – possibly on a different processor  Each booking transaction must check seat availability before reserving the seat

Thread synchronisation Seat reservation database Booking agent 1 Booking agent 2 ….. Booking agent n Check availability Reserve seat Check availability Reserve seat Check availability Reserve seat

Thread synchronisation Pseudo-code for booking a seat Pseudo-code for booking a seat if seat n is available book seat n; Code not atomic Code not atomic  For an unsynchronised thread it can be pre- empted by another thread after the if statement  The thread might think the seat is available but it then might be booked by the pre-empting thread  The seat will be double booked

Thread synchronisation Booking agent 1 Booking agent 2 check availability book seat pre-empted re-schedule Unsynchronised threads

Thread synchronisation We will first show the code for an unsynchronised application We will first show the code for an unsynchronised application  This will lead to double bookings where a seat can be booked twice We will then show how we can sychronize the thread access to the shared object thus eliminating double bookings with minimal code changes We will then show how we can sychronize the thread access to the shared object thus eliminating double bookings with minimal code changes

Thread synchronisation 2 main classes 2 main classes  SeatBookings  Contains the seat booking information (just a simple array)  Contains isAvailable() and bookSeat() methods which access the seat booking information  BookingAgent  Contains a reference to a SeatBookings object which is thus a shared object between all of the BookingAgent objects

Thread synchronisation class SeatBookings { private int[] seats; public int totalBooked = 0; public SeatBookings(int[] s) { seats=s; } public bool isAvailable(int seatno) { return (seats[seatno] == 0); } public void bookSeat(int seatno) { if (isAvailable(seatno)) { seats[seatno]++; totalBooked++; Console.WriteLine("Seat " + seatno + " booked. Total booked= " + totalBooked); } public bool doubleBooked(int seatno) { return (seats[seatno] > 1); }

Thread synchronisation class BookingAgent { private SeatBookings sb; private int agent; private Random randomNumers=new Random(); public BookingAgent(SeatBookings s, int a) { sb=s; agent=a; } public int getAgent() { return agent; } public void bookSeat() { do { int seatno = (int)(randomNumers.Next(0, 1000)); sb.bookSeat(seatno); if (sb.doubleBooked(seatno)) Console.WriteLine("Seat number " + seatno + " double booked!"); } while (sb.totalBooked<1000); Console.WriteLine("All bookings complete"); }

Thread synchronisation using System; using System.Threading; public class SeatBookingApp { static void Main(string[] args) { int[] seats=new int[1000]; for (int j=0; j<1000; j++) seats[j]=0; BookingAgent[] b=new BookingAgent[10]; SeatBookings s=new SeatBookings(seats); Thread[] bookingThreads= new Thread[10]; for (int i=0; i<10; i++) { b[i] = new BookingAgent(s, i); bookingThreads[i]=new Thread(new ThreadStart(b[i].bookSeat)); bookingThreads[i].Start(); }

Thread synchronisation Demos\Thread Synch\SeatBookingAppUnsynch.exe Demos\Thread Synch\SeatBookingAppUnsynch.exe Demos\Thread Synch\SeatBookingAppUnsynch.exe Demos\Thread Synch\SeatBookingAppUnsynch.exe

Thread synchronisation We can synchronise the threads by ensuring that the SeatBookings.bookSeat() method is enclosed by Monitor.Enter() and Monitor.Exit() We can synchronise the threads by ensuring that the SeatBookings.bookSeat() method is enclosed by Monitor.Enter() and Monitor.Exit()  The SeatBookings object is then locked by the thread which has current access SeatBookings object Booking agent 1 Booking agent 2 locked locked out

Thread synchronisation class SeatBookings { private int[] seats; public int totalBooked = 0; public SeatBookings(int[] s) { seats = s; } public bool isAvailable(int seatno) { return (seats[seatno] == 0); } public void bookSeat(int seatno) { Monitor.Enter(this);// Lock object if (isAvailable(seatno)) { seats[seatno]++; totalBooked++; Console.WriteLine("Seat " + seatno + " booked. Total booked= " + totalBooked); } Monitor.Exit(this); } public bool doubleBooked(int seatno) { return (seats[seatno] > 1); }

Thread synchronisation Synchronised threads Booking agent 1Booking agent 2 check availability book seat check availability book seat check availability book seat

Thread synchronisation Demos\Thread Synch\SeatBookingAppSynch.exe Demos\Thread Synch\SeatBookingAppSynch.exe Demos\Thread Synch\SeatBookingAppSynch.exe Demos\Thread Synch\SeatBookingAppSynch.exe

Multi-threading and GUI’s Multiple threads updating GUI components are not predictable Multiple threads updating GUI components are not predictable  GUI components are not thread safe  All updates to GUI components should be done in the User Interface (UI) Thread  For example, writing to a label .NET provides an Invoke method of class Control to specify which GUI processing statements will be executed in the UI thread

Multi-threading and GUI’s Method Invoke() takes a delegate object as an argument which is initialized with the method that is to be called in the UI thread Method Invoke() takes a delegate object as an argument which is initialized with the method that is to be called in the UI thread  We can also include a parameter list for the initializer method myGUIComponent.Invoke(new myDelegate(myMethod)); myGUIComponent.Invoke(new myDelegate(myMethod),new object[] {arg1,arg2...});

Multi-threading and GUI’s The following application interacts with a GUI to suspend thread execution by clicking on a checkbox control The following application interacts with a GUI to suspend thread execution by clicking on a checkbox control Also the text label is updated to indicate a suspended thread Also the text label is updated to indicate a suspended thread

Multi-threading and GUI’s Demos\Threads and GUIs\GUIThreadsForm.exe Demos\Threads and GUIs\GUIThreadsForm.exe Demos\Threads and GUIs\GUIThreadsForm.exe Demos\Threads and GUIs\GUIThreadsForm.exe

using System; using System.Windows.Forms; using System.Threading; public partial class GUIForm : Form { private Counter c1,c2,c3; public GUIForm() {InitializeComponent();} private void checkBox1_CheckedChanged(object sender, EventArgs e) { if (sender == checkBox1) c1.toggle(); else if (sender == checkBox2) c2.toggle(); else if (sender == checkBox3) c3.toggle(); } private void GUIForm_Load(object sender, EventArgs e) { c1 = new Counter(label1); Thread thread1 = new Thread(new ThreadStart(c1.count)); thread1.Name = "Thread 1"; thread1.Start(); c2 = new Counter(label2); Thread thread2 = new Thread(new ThreadStart(c2.count)); thread2.Name = "Thread 2"; thread2.Start(); c3 = new Counter(label3); Thread thread3 = new Thread(new ThreadStart(c3.count)); thread3.Name = "Thread 3"; thread3.Start(); }

class Counter { private bool suspended; private Label output; private string threadName; private int currentCount=0; public Counter(Label l) {output=l; suspended=false;} private delegate void DisplayDelegate(int count); private void DisplayCount(int count) {output.Text=threadName+ ": " + count;} public void count() { threadName = Thread.CurrentThread.Name; while (true) { Thread.Sleep(300); lock(this) { while (suspended) {Monitor.Wait(this);} } currentCount++; output.Invoke(new DisplayDelegate(DisplayCount), new object[] {currentCount}); } public void toggle() { suspended = !suspended; output.BackColor = suspended ? Color.Red : Color.LightCyan; lock (this) { if (!suspended) Monitor.Pulse(this); }

Summary We have seen how we can create a multi threaded program using the Thread class and the ThreadStart () delegate We have seen how we can create a multi threaded program using the Thread class and the ThreadStart () delegate We have seen how threads are scheduled and how threads can exist in different states and run with different priority levels We have seen how threads are scheduled and how threads can exist in different states and run with different priority levels We have looked at how we can synchronise threads so that they maintain consistency when accessing shared objects We have looked at how we can synchronise threads so that they maintain consistency when accessing shared objects We have looked at the use of the Control.Invoke() method for calling methods in the UI thread enabling GUI components to be updated in a multithreaded program We have looked at the use of the Control.Invoke() method for calling methods in the UI thread enabling GUI components to be updated in a multithreaded program We have only scratched the surface. For an excellent and thorough description of threading see We have only scratched the surface. For an excellent and thorough description of threading see