Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object Oriented Programming Multithreading Dr. Mike Spann

Similar presentations


Presentation on theme: "Object Oriented Programming Multithreading Dr. Mike Spann"— Presentation transcript:

1 Object Oriented Programming Multithreading Dr. Mike Spann m.spann@bham.ac.uk

2 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

3 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

4 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)

5 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

6 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"); }

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

8 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

9 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

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

11 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(); }

12 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); }

13 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

14 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

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

16 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

17 Thread states Unstarted Running Start() WaitSleepJoin StoppedBlocked

18 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()

19 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

20 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

21 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

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

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

24 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(); }

25 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(); }

26 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

27 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 < 100000; i++) total += i; } static void Main(string[] args) { Thread thread1 = new Thread(new ThreadStart(Adder)); thread1.Start(); thread1.Join(); Console.WriteLine("The total= " + total); }

28 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

29 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(); }

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

31 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

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

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

34 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

35 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 }

36 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

37 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

38 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

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

40 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

41 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

42 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); }

43 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"); }

44 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(); }

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

46 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

47 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); }

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

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

50 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

51 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...});

52 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

53 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

54 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(); }

55 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); }

56 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 www.albahari.com/threading We have only scratched the surface. For an excellent and thorough description of threading see www.albahari.com/threading www.albahari.com/threading


Download ppt "Object Oriented Programming Multithreading Dr. Mike Spann"

Similar presentations


Ads by Google