1 / 56

Object Oriented Programming

Object Oriented Programming. Multithreading. Dr. Mike Spann m.spann@bham.ac.uk. Contents. Introduction Creating and executing threads Simple example – a counter thread Thread priority and thread scheduling Thread states Thread synchronisation Multi-threading and GUI’s Summary.

Download Presentation

Object Oriented Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

  3. Introduction • 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 • 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) • 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 • Switching between threadsinvolves 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 • 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 • In simple use, this method must have no parameters and return void • 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 • 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) { MyClassmyObject=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. Main() thread new thread created new thread Code in myMethod() executed Creating and executing threads

  8. Simple example – a counter thread • 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 • 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

  10. Simple example – a counter thread Main thread Create counter 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 intnThread = 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 intthreadCount; public CounterForm(inttc) { 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 • 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

  14. Thread priority and thread scheduling • .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 A B AboveNormal Priority C Normal Priority BelowNormal Priority D E Lowest Priority F

  16. Thread states • At anyone time, a thread can exist in one of a number of states • 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 • 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 Start() Running WaitSleepJoin Stopped Blocked

  18. Thread states Unstarted Start() Running Completed Abort() Stopped • 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

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

  20. Thread states • 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 Moniterobject’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 • 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 Creates thread t Main thread Calls t.Join() Main thread suspends execution Thread t terminates Main thread resumes

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

  24. Thread states 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(); } } Example 1. Putting a thread to sleep

  25. Thread states 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(); } } • Example 2. Interrupting a sleeping thread • Causes an exception to be thrown

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

  27. ThreadStates 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); } } Example 3. Synchronising 2 threads using Join()

  28. ThreadStates • 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() • Demos\Thread States\ThreadSynch.exe

  29. Thread states 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(); } } } Example 4. A watchdog timer using Join()

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

  31. Thread synchronisation • 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 do this by giving one thread at a time exclusive access to code that manipulates shared objects

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

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

  34. Thread synchronisation • A thread can lock a shared object so that it has exclusive access to it • 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 lock(anObject) { // Synchronized code here } 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

  36. Thread synchronisation • 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 Booking agent 2 ….. Booking agent n Booking agent 1 Check availability Reserve seat Check availability Reserve seat Check availability Reserve seat Seat reservation database

  38. Thread synchronisation • Pseudo-code for booking a seat if seat n is available book seat n; • 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 Unsynchronised threads Booking agent 1 Booking agent 2 check availability pre-empted re-schedule book seat

  40. Thread synchronisation • 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

  41. Thread synchronisation • 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 inttotalBooked = 0; public SeatBookings(int[] s) { seats=s; } public boolisAvailable(intseatno) { return (seats[seatno] == 0); } public void bookSeat(intseatno) { if (isAvailable(seatno)) { seats[seatno]++; totalBooked++; Console.WriteLine("Seat " + seatno + " booked. Total booked= " + totalBooked); } } public booldoubleBooked(intseatno) { return (seats[seatno] > 1); } }

  43. Thread synchronisation class BookingAgent { private SeatBookingssb; private int agent; private Random randomNumers=new Random(); public BookingAgent(SeatBookings s, int a) { sb=s; agent=a; } public intgetAgent() { return agent; } public void bookSeat() { do { intseatno = (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

  46. Booking agent 2 Booking agent 1 locked out locked SeatBookings object Thread synchronisation • 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

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

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

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

  50. Multi-threading and GUI’s • 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

More Related