NETWORK PROGRAMMING CNET 441 CHAPTER 4 Multithreading Chapter

  • Slides: 25
Download presentation
NETWORK PROGRAMMING CNET 441 CHAPTER - 4 Multithreading

NETWORK PROGRAMMING CNET 441 CHAPTER - 4 Multithreading

Chapter 4: Objectives After Completing the Chapter 4, the student can understand the following

Chapter 4: Objectives After Completing the Chapter 4, the student can understand the following concepts. • Thread Basics • Using Threads in Java Extending the Thread Class Sample Program Implementing the Runnable Interface Sample Program • Multithreaded Servers • Locks and Deadlock • Synchronising Threads 2

Thread Basics • A thread is a flow of control through a program. •

Thread Basics • A thread is a flow of control through a program. • A thread does not have a separate allocation of memory, but shares memory with other threads created by the same application. • Threads created by an application can share global variables. • Threads can have its own local variables. 3

Pre-emptive and Cooperative Scheduler 1. A pre-emptive scheduler will determine when a thread has

Pre-emptive and Cooperative Scheduler 1. A pre-emptive scheduler will determine when a thread has had its fair share of CPU time (possibly via simple time allocation) and will then pause it (temporarily). 2. A cooperative scheduler, on the other hand, will wait for the running thread to pause itself before giving control of the CPU to another thread. 4

Methods for Creating Thread Class In Java, an object can be run as a

Methods for Creating Thread Class In Java, an object can be run as a thread if it implements the inbuilt interface Runnable, which has just one method: run. Thus, in order to implement the interface, we simply have to provide a definition for method run. Since the inbuilt class Thread implements this interface. There are two fundamental methods for creating a thread class. create a class that extends Thread. create a class that does not extend Thread and specify explicitly that it implements Runnable. 5

Extending the Thread Class 1. The run method specifies the actions that a thread

Extending the Thread Class 1. The run method specifies the actions that a thread is to execute and serves the same purpose for the process running on the thread as method main does for a full application program. 2. Like main , run may not be called directly. The containing program calls the start method (inherited from class Thread ), which then automatically calls run. 3. The two most commonly used constructors are: Thread() Thread(String<name>) 6

Extending Thread Class (cont. . ) 7

Extending Thread Class (cont. . ) 7

Thread Class Constructors Thread( ): If this method is used, the system generates a

Thread Class Constructors Thread( ): If this method is used, the system generates a name of the form Thread-n, where n is an integer, starting at zero and increasing in value for further threads. Thus, if three threads are created via the first constructor, they will have names Thread-0 , Thread-1 and Thread -2 respectively. Thread(String<name>): This method provides a name for the thread via its argument. Note: Whichever constructor is used, method get. Name may be used to retrieve the name. Example: Thread first. Thread = new Thread(); Thread second. Thread = new Thread("named. Thread"); System. out. println(fi rst. Thread. get. Name()); System. out. println(second. Thread. get. Name()); 8

Thread Life Cycle 9

Thread Life Cycle 9

sleep( ) and interrupt( ) Methods sleep( ) method: This method is used to

sleep( ) and interrupt( ) Methods sleep( ) method: This method is used to make a thread pause for a specified number of milliseconds. Example: my. Thread. sleep(1500); //Pause for 1. 5 seconds. interrupt( ) method: This method may be used to interrupt an individual thread. In particular this method may be used by other threads to awaken a sleeping thread before that thread’s sleeping time has expired. Note: Please refer the Example in the Text Book. 10

Explicitly Implementing the Runnable Interface 1. We first create an application class that explicitly

Explicitly Implementing the Runnable Interface 1. We first create an application class that explicitly implements the Runnable interface. 2. Then, in order to create a thread, we instantiate an object of our Runnable class and wrap it in a Thread object. We do this by creating a Thread object and passing the Runnable object as an argument to the Thread constructor. 3. There are two Thread constructors that allow us to do this. Thread (Runnable<object>) Thread(Runnable<object>, String<name>) Example - Please Refer Text Book 11

Multithreading 12

Multithreading 12

Single-Threaded Server 13

Single-Threaded Server 13

Multithreaded Server 14

Multithreaded Server 14

Multithreaded Servers Why use Multithreaded Server? There is a fundamental and important limitation associated

Multithreaded Servers Why use Multithreaded Server? There is a fundamental and important limitation associated with all the server programs encountered so far. v They can handle only one connection at a time. v This restriction is simply not feasible for most real-world applications and would render the software useless. v There are two possible solutions: use a non-blocking server use a multithreaded server 15

Advantages of Multithreaded Servers: v It offers a clean implementation, by separating the task

Advantages of Multithreaded Servers: v It offers a clean implementation, by separating the task of allocating connections from that of processing each connection. v It is robust, since a problem with one connection will not affect other connections. 16

Multithreaded Socket Server 17

Multithreaded Socket Server 17

Multithreaded Server Process 1. The basic technique involves a two-stage process: The main thread

Multithreaded Server Process 1. The basic technique involves a two-stage process: The main thread (the one running automatically in method main ) allocates individual threads to incoming clients. The thread allocated to each individual client then handles all subsequent interaction between that client and the server (via the thread’s run method). Note: Please refer the example program in the Text Book. 18

Locks 1. We can require a thread to obtain a lock on the object

Locks 1. We can require a thread to obtain a lock on the object that is to be updated. 2. Only the thread that has obtained the lock may then update the object. Any other (updating) thread must wait until the lock has been released. 3. Once the first thread has finished its updating, it should release the lock, making it available to other such threads. (Note that threads requiring read-only access do not need to obtain a lock). 19

Deadlocks 20

Deadlocks 20

Deadlocks (cont. . ) 1. A state of deadlock occurs when threads are waiting

Deadlocks (cont. . ) 1. A state of deadlock occurs when threads are waiting for events that will never happen. 2. Consider the example illustrated in Fig. 3. 5. Here, thread 1 has a lock on resource res 1 , but needs to obtain a lock on res 2 in order to complete its processing (so that it can release its lock on res 1 ). 3. At the same time, however, thread 2 has a lock on res 2 , but needs to obtain a lock on res 1 in order to complete its processing. 21

Synchronising Threads Locking is achieved by placing the keyword synchronized in front of the

Synchronising Threads Locking is achieved by placing the keyword synchronized in front of the method definition or block of code that does the updating. Example public synchronized void update. Sum(int amount) { sum+=amount; } 22

Synchronising Threads (cont. . ) In order to improve thread efficiency and to help

Synchronising Threads (cont. . ) In order to improve thread efficiency and to help avoid deadlock, the following methods are used: wait() notify. All() wait() method: 1. If a thread executing a synchronized method determines that it cannot proceed, then it may put itself into a waiting state by calling method wait. 2. This releases the thread’s lock on the shared object and allows other threads to obtain the lock. 23

notify() and notify. All() methods notify() method: When a synchronized method reaches completion, a

notify() and notify. All() methods notify() method: When a synchronized method reaches completion, a call may be made to notify, which will wake up a thread that is in the waiting state. notify. All() method: If all threads waiting for a lock on a given object are to be woken, then we use notify. All. Note: Please refer the producer-consumer problem example from the Text Book. 24

wait(), notify. All() methods 25

wait(), notify. All() methods 25