1 / 39

2. Threads and Multithreaded Client/Server Applications

2. Threads and Multithreaded Client/Server Applications. Goal: Provide the ability to execute segments of code of the same program concurrently, and use multiple processors when working on a multiprocessor machine.

lovern
Download Presentation

2. Threads and Multithreaded Client/Server Applications

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. 2. Threads and Multithreaded Client/Server Applications Goal: Provide the ability to execute segments of code of the same program concurrently, and use multiple processors when working on a multiprocessor machine. Examples: Single server serves more than one client; GUI programs have separate interface for gathering user interface events. Main Idea: Extend multitasking, ( the ability to execute more than one program concurrently or concurrent processes), one level lower, namely to the ability to execute concurrent sequences, or threads, within a single program Multitasking can be Preemptive: OS interrupts program without consulting it first (more effective, but harder to implement) Cooperative: program interrupted only when willing to yield (easier to implement, but a bad program can clog up system) CS 667: 2. Multithreading Zlateva

  2. 2.1. Lightweight Processes Thread (of control/execution) or Lightweight Process: a less protected and thus less expensive version of the traditional computing process • shares with other threads • global data such as global and static variables; • heap holding dynamically allocated data • open files (descriptors); • etc. creation is 10-100 times faster than process creation • has its own • thread ID; • stack holding local variables, method arguments; • registers, such as • program counter and • stack pointer; • etc. CS 667: 2. Multithreading Zlateva

  3. user creates threads and is responsible for their integrity operating system creates and manages process and is responsible for its integrity Processes & Threads • Process: can have one or more threads of execution that share • process instructions (machine code translated from source code); • most data: global data, and dynamically allocated data on the heap, e.g. by the new operator; • open files; • signal handlers, signal dispositions • current working directories, • user and group IDs; • Thread: own • thread ID; • stack (local variables, method arguments) • registers: program counter, stack pointer, etc. • Thread: own • thread ID; • stack (local variables, method arguments) • registers: program counter, stack pointer, etc. CS 667: 2. Multithreading Zlateva

  4. Thread States • State A thread is in this state when • new Thread has been created with new operator: It is not yet running, • as some bookkeeping must be done before it can execute; the • bookkeeping is done by the start method, after that the thread transitions in state runnable • runnable thread is ready to run or is running. Although in runnable state • the thread may or may not be running. It is up to the operating system to give it CPU time. The decision is OS-specific, e.g • green threads package used by JDK 1.x on Solaris keeps thread running until a higher priority thread claims control, Windows 95 • and NT give time slices to perform its task (better), current • Solaris releases can be configured to use native Solaris • and time-slicing CS 667: 2. Multithreading Zlateva

  5. Thread States (continued) • State A thread is in this state when • blocked - sleep method has been called, • - thread has called an operation that blocks input/output, • - thread calls wait method • - tries to lock object that is currently locked by other thread • - someone calls the suspend method on the thread • (Note: suspend is deprecated, do not use it) • To leave the blocked state a thread must reverse the above actions, i.e. • - specified number of msec in sleep have elapsed, • - operation that blocks input/output has completed • - if wait called, another thread has called notify or notifyAll, • - if it waits for object lock owned by another thread, • the other thread has released the lock • - if suspend called on the thread someone must call resume • (Note: resume is deprecated, do not use it) CS 667: 2. Multithreading Zlateva

  6. sleep start wait runnable blocked new dead block on i/o suspend/resume Thread States (continued) • State A thread is in this state when • dead - run method exits normally • - uncaught exception terminates run • - stop method called on thread • (Note: stop is deprecated, do not use it) run exits notify stop CS 667: 2. Multithreading Zlateva

  7. Threads Pros and Cons • Threads • allow concurrent execution of segments of the same program. This is unlike multi-tasking where processes run concurrently each with its own data space; • are less protected thus less expensive (10-100 faster creation than • process); • are created and managed by the user. (As opposed to this the process is created and managed by the OS: The operating system will resolve conflicts for the process, but does not care whether the process is single or multithreaded and what conflicts that may arise between process threads); • must be synchronized by user to avoid conflict, i.e. user is • responsible for the integrity of the thread, typically with the • mechanism of mutual exclusion. CS 667: 2. Multithreading Zlateva

  8. a) Create Subclass: Example:class SubThread extends Thread General:class <sub-thread-name> extends Thread The Thread class is the run time representation of a thread, and a thread object, a language thread, can pause, resume and stop the corresponding system thread. b) Instantiate subclass object: An object is instantiated as usual through: SubThread myThread = new SubThread(); The above statement only instantiates an object, it does not start a thread. In order to start a thread we need to call the Thread start() method. Thus we need to c) Call the Thread start() method with the subclass object myThread.start(); The start() method will then automatically call the Thread method run() . The run method must specify all actions to be performed by the subclass thread, i.e. it must be defined in the subclass and override the base class method. 2.2. Creating and Starting a Java Thread - I.Extending the Thread class CS 667: 2. Multithreading Zlateva

  9. Class Thread - Constructors Provided by java.lang package Represents the run time behavior of threads. Some of the more frequently used methods are: Constructors: Thread ( ) - allocates new Thread object Thread ( String <thread-name> ) - creates thread with <thread-name>; handy to identify threads for debugging purposes. Thread ( <runnable target> ) - creates thread in <runnable target> that must be an object that implements Runnable. The newly created thread is asleep, not running yet; to put it in the running state the start method must be called, which then automatically calls the run method CS 667: 2. Multithreading Zlateva

  10. Thread - Control Methods Instance Methods : void start ( ) actually starts thread, automatically calls run void run ( ) internal method called when thread started void interrupt( ) if target thread is blocked (e.g. after sleep or wait) interrupt aborts this state immediately with an InterruptedException; if thread is not blocked but subsequently enters the blocked state, interrupt() will abort the blocked state at that later point; the interrupted() method can be used to check for an outstanding interrupt; particularly useful as alternative to stop() void suspend ( ) suspends execution until another thread calls resume, deprecated as known to be deadlock prone. void resume( ) resumes execution, valid only after suspend. void stop ( )stops execution deprecated as known to be inherently unsafe CS 667: 2. Multithreading Zlateva

  11. Thread - Control Methods (continued) Static Methods : static void sleep ( long <milliseconds> ) throws InterruptedException causes current thread to sleep the specified number of <milliseconds>; try{ Thread.sleep(1000); // sleep for 1 sec } catch(InterruptedException e){ System.out.println("I was interrupted"); the thread will wake up if another thread has a reference to it and calls its interrupt method. static void yield ( ) causes current thread to yield the processor to waiting threads; the language does not guarantee preemption, thus this method should always be called when long computations are performed. CS 667: 2. Multithreading Zlateva

  12. Instance Methods: int getPriority ( ) returns thread priority. Every thread has a priority attribute. The priority ranges from MIN_PRIORITY (1), through NORM_PRIORITY (5) to MAX_PRIORITY(10). When a thread is first created its priority is set by default to the priority of its parent thread, usually 5. Whenever the thread-scheduler picks a new thread it generally picks the one with the highest priority. Thus if a thread should be given an advantage one must increase its priority. (main() has NORM_PRIORITY.) void setPriority( int <new-priority> ) sets thread priority to <new-priority> boolean isAlive ( ) returns true if thread is currently alive (in running state) boolean isInterrupted ( ) returns true if thread has been interrupted and has not yet received an InterruptedException. Does not clear condition if it is set. Thread - Service Methods CS 667: 2. Multithreading Zlateva

  13. Thread - Service Methods (continued) Static Methods: static int activeCount( ) returns the number of currently active threads static Thread currentThread( ) returns tread object corresponding to the currently executing thread static boolean interrupted ( ) returns true if the current thread has been interrupted and has not yet received an InterruptedException, then clears interrupted flag (unlike isInterrupted which does not). Note that interrupted is a static method, while isInterrupted is called on the current Thread instance. For an extended overview see (HoCo 2002, Ch.1), (HSH 1999, Ch.4), and there are a good number of texts specifically devoted to threads that provide further details. CS 667: 2. Multithreading Zlateva

  14. a) Create a class (sometimes called a runnable class) that implements Runnable: Example:class CanBeThreaded implements Runnable General:class <threaded-class-name> implements Runnable The Runnable interface allows the creation of threads in objects that do not directly extend the Thread class. This interface contains the run() method that must be overridden to specify the actions for the particular thread. If an object implements the Runnable interface a (or many) thread(s) can be started in this object. This is done by passing the object as an argument, target, to Thread b) Instantiate objects of class that implements Runnable CanBeThreaded objRunnable1 = new CanBeThreaded(); CanBeThreaded objRunnable2 = new CanBeThreaded(); II.Runnable class object as Thread argument CS 667: 2. Multithreading Zlateva

  15. c) Createthreads in objects of class that implement Runnable Thread execute1 = new Thread(objRunnable1); Thread execute2 = new Thread(objRunnable2); Thread execute3 = new Thread(objRunnable2); d) Call the Thread start() method with the thread objects execute1.start(); execute2.start(); execute3.start(); Note: Many threads can be created/started in the same object. Runnable …(continued) CS 667: 2. Multithreading Zlateva

  16. The Runnable Interface Goal: Provide ability to create objects that do not extend the Thread class and thus allow to implement a version of "multiple inheritance". The interface has only one method void run ( ) this is the method that is executed when the thread is stared; thus it must be provided for the specific class. The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments called run. This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread. Being active simply means that a thread has been started and has not yet been stopped. CS 667: 2. Multithreading Zlateva

  17. Runnable (continued) In addition, Runnable provides the means for a class to be active while not subclassing Thread. A class that implements Runnable can run without subclassing Thread by instantiating a Thread instance and passing itself in as the target. In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class. CS 667: 2. Multithreading Zlateva

  18. In In Method II the class is a regular class (not a thread) but implements Runnable, thus is a class that can be treaded if/when needed: • has only its own methods, no access to the Thread methods, • the thread controls - start, stop, sleep,etc - are accessed from outside the class • thread is spawned, then object attached to it and started, we say "thread in object started"; but the object can be run in a process just the same - it does not care or know whether it is run as a thread or process, • allows to perform a version of C++ multiple inheritance (not available in Java) class object class object process thread thread class object Methods I and II are equivalent in that both create and start a thread. Some more important differences are: Thread Subclass vs. Runnable Class • In Method I the entire class is a thread: • it inherits all methods of the Thread class, thus giving a nice free functionality • the thread controls - start, stop, sleep,etc - are accessed from within the class • as the class is threaded, if you want to use the class functionality without threads, you have to create an equivalent non-threaded class or choose Method II. • as Java does not support multiple inheritance, the Thread subclass cannot inherit from another class CS 667: 2. Multithreading Zlateva

  19. Java Supports Threads at the Language Level The main goal of multithreading is to allow concurrency within the execution of the same program. Threads share the data/address space. Thus when global or static variables are changed all threads see the change. (Note difference to multitasking where every process has its own address space.) In a multiprocessor machine threads actually do run on different processors, thus upgrading performance even for simple applications. Typically threads are implemented in helper libraries and are not trivial to program. Java supports threads natively at the language level, which is easier for programming. There is a one-to-one correspondence between Thread objects and actual language threads. The language threads are controlled by calling methods in the corresponding Thread object. CS 667: 2. Multithreading Zlateva

  20. 2.3. Thread and Variable Scope • Variables local to thread • Include: • All variables declared within the execution of the thread, • All method arguments. • Properties: • stored in the thread's local stack and • are not visible to other threads. • Variables shared by all threads • Include: • Global and static variables of program. • Instance variables of program (Note instance variables are also referred as local variables, but they are local to the program process, not to the threads within the process) • Properties: • stored in global storage or heap, • visible to all threads CS 667: 2. Multithreading Zlateva

  21. Example non-local to thread running aMethod() static class TestScope{ static int steady = 15; ArrayList classList= new ArrayList(); void aMethod(int param){ float fleeting = steady; classList.add(new Float(fleeting)); } } local to aMethod() & to thread running aMethod(): every thread running aMethod() has its own 'param' and 'fleeting' allocated. instance variable, non-local to aMethod() Change to a variable (classList) seen by all threads through a local thread variable (fleeting) : 'classList' is shared by all threads calling aMethod() on the same instance/object of TestScope class, but 'fleeting is a local thread variable Note that thread local references may refer to and change a non local object. The change is then visible to all threads, and it should be coordinated, or synchronized, with their work. (for more see HSH, Ch.4, p.35ff) CS 667: 2. Multithreading Zlateva

  22. 2.4. Multithreaded Client/Server ExamplesExample 1a: Threaded Echo Server with Thread Subclass(Ex.3-3, HoCo 2002, p.207) import java.io.*; import java.net.*; /** * @(#) ThreadedEchoServer.java */ public class ThreadedEchoServer{ static public void main(String argv[]){ int i = 1; try{ ServerSocket s = new ServerSocket (8189); for(;;){ Socket incoming = s.accept(); System.out.println("Spawning " + i); new ThreadedEchoHandler(incoming,i).start(); i++; } }catch(IOException io){ io.printStackTrace(); } } CS 667: 2. Multithreading Zlateva

  23. Example1a: (continued) class ThreadedEchoHandler extends Thread{ public ThreadedEchoHandler(Socket s, int i){ incoming = s; counter = i; } public void run(){ try{ BufferedReader in = new BufferedReader( new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter(incoming.getOutputStream(), true); out.println("Hello! Enter BYE to exit."); CS 667: 2. Multithreading Zlateva

  24. boolean done = false; while(!done){ String line = in.readLine(); if(line == null) done = true; else{ out.println("Echo(" + counter + "): "+line); if(line.trim().equals("BYE")) done = true; } //end else-clause } //end while incoming.close(); }catch(Exception e){ System.out.println(e); } //end try } //end run private Socket incoming; private int counter; } Example1a: (continued) CS 667: 2. Multithreading Zlateva

  25. Example1b: Threaded Echo Server with Runnable Interface public class ThreadedEchoServerR{ static public void main(String argv[]){ int i = 1; try{ ServerSocket s = new ServerSocket(8189); for(;;){ Socket incoming = s.accept(); ThreadedEchoHandlerR handler = new ThreadedEchoHandlerR( incoming, i); System.out.println("Spawning " + i); Thread t = new Thread ( handler ); t.start(); i++; } }catch(IOException io){ io.printStackTrace(); } a runnable object not a thread!! Now a thread is created in runnable object handler CS 667: 2. Multithreading Zlateva

  26. Example1b: (continued) class ThreadedEchoHandlerR implements Runnable{ ThreadedEchoHandlerR(Socket s, int i) { incoming=s; counter = i;} public void run(){ try{ BufferedReader in = new BufferedReader( new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter(incoming.getOutputStream(), true); out.println("Hello! Enter BYE to exit."); …. must be provided for the runnable interface Remaining code identical to the code the implementation extending Thread CS 667: 2. Multithreading Zlateva

  27. Server Side Server extends Thread Server() run() main() Connects extends Thread Connects(Socket) run() ArrayIO ArrayIO() writeArray(DataOutputStream, int[]) int[] readArray(BufferedReader) printArray(String, int[]) ArrayMath Client Side Client main() ArrayIO ArrayIO() writeArray( …) int[] readArray(….) printArray(String, int[]) 2.4. Example: Array Arithmetic Client/Server Application CS 667: 2. Multithreading Zlateva

  28. Example2: Array Arithmetic - Server1 import java.io.*; import java.net.*; import java.util.*; /** *@(#)Server.java */ class Server1 extends Thread { // Note: Server is a Thread public static final int MATH_PORT=5555; protected ServerSocket listener; //Constructor public Server1() { try{ listener = new ServerSocket(MATH_PORT); }catch(IOException ioe){ System.out.println("Exception..."+ioe); } this.start(); //server thread started } CS 667: 2. Multithreading Zlateva

  29. Example2: Server1 (continued) //Multithreading: new thread for each request public void run() { System.out.println("Server for Array Arithmetic started..."); int counter=1; try{ while(true){ Socket client=listener.accept(); System.out.println("Spawning " + counter); Connects cc = new Connects(client); //runs thread in client counter++; } }catch(IOException iox){ System.out.println("Exception..."+iox); } } //end run //Main public static void main(String argv[]) throws Exception{ new Server1(); } } CS 667: 2. Multithreading Zlateva

  30. //Thread subclass for each new client class Connects extends Thread{ Socket client; BufferedReader is; DataOutputStream os; ArrayIO aio = new ArrayIO(); ArrayMath ad = new ArrayMath(); //Constructor public Connects(Socket s){ client = s; try{ is = new BufferedReader(newInputStreamReader(client.getInputStream())); os = new DataOutputStream(client.getOutputStream()); }catch(IOException e){ try{ client.close(); }catch(IOException ex){ System.out.println("Error getting socket streams:"+ex); } } this.start(); } //end Connects constructor Example2: Server1 (continued) CS 667: 2. Multithreading Zlateva

  31. //run for client Connects thread public void run() { int a[] = new int[16]; int b[] = new int[16]; try{ a = aio.readArray(is); b = aio.readArray(is); }catch(Exception ior){ ior.printStackTrace(); } int temp[] = new int[16]; temp = ad.addArray(a,b); try{ aio.writeArray(os, temp); }catch(Exception e){ e.printStackTrace(); } } }//end Connects class Example2: Server1 (continued) CS 667: 2. Multithreading Zlateva

  32. Example2: ArrayIO import java.io.*; /** *@(#)ArrayIO.java */ class ArrayIO{ public ArrayIO( ) { } /** * Write int array to socket */ public void writeArray(DataOutputStream out, int arr[]) throws Exception { for(int i=0; i<arr.length; i++) out.write(arr[i]); } CS 667: 2. Multithreading Zlateva

  33. Example2: ArrayIO (continued) /** * Reads int array from socket, returns int array z */ public int[] readArray(BufferedReader b) throws Exception { int z[] = new int[16]; for(int j=0; j<z.length; j++){ try{ z[j] = (int)b.read(); }catch(IOException ioe){ ioe.printStackTrace(); } } return z; } } CS 667: 2. Multithreading Zlateva

  34. Example2: ArrayMath import java.io.*; /** *@(#)ArrayMath.java */ class ArrayMath { public ArrayMath( ) {} /** * method for adding two int arraya */ public int[] addArray(int a[], int b[]) { int sum[] = new int[16]; for(int i=0; i<sum.length; i++) sum[i] = a[i] + b[i]; return sum; } } CS 667: 2. Multithreading Zlateva

  35. Example2: Client import java.io.*; import java.net.*; /** *@(#)Client.java */ class Client{ public final static int REMOTE_PORT=5555; static int x[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; static int y[]={2,2,2,2,2,2,2,2,2,2, 2, 2, 2, 2, 2, 2}; public static void main(String argv[]) throws Exception{ //Socket and IO stream objects creation Socket s = null; BufferedReader is = null; DataOutputStream os = null; ArrayIO aio = new ArrayIO(); CS 667: 2. Multithreading Zlateva

  36. Example2: Client (continued) //Bind IO streams to socket try{ s = new Socket(InetAddress.getByName("localhost"),REMOTE_PORT); is = new BufferedReader(new InputStreamReader(s.getInputStream())); os = new DataOutputStream(s.getOutputStream()); }catch (UnknownHostException e1){ System.out.println("Unknown Host: "+e1); }catch (IOException e2){ System.out.println("Error io: "+e2); } CS 667: 2. Multithreading Zlateva

  37. Example2: Client (continued) //Send arrays x, y to server try{ aio.writeArray(os, x); aio.writeArray(os, y); } catch (IOException ew){ System.out.println("Error writing to server: "+ew); } //Receive sum of arrays x,y from server int sum[] = new int[16]; try{ sum = aio.readArray(is); }catch (Exception e){ e.printStackTrace(); } CS 667: 2. Multithreading Zlateva

  38. Example2: Client (continued) //Print results for(int k=0; k<sum.length; k++) System.out.print(sum[k]+" "); System.out.println(""); //Close io streams and connection try{ is.close(); os.close(); s.close(); }catch (IOException x){ System.out.println("Error writing ..."+x); } } } CS 667: 2. Multithreading Zlateva

  39. Example2: Server2 'exit' to terminate server (different run)Not a good idea!! //Server thread run -> Multithreading: new thread for each request public void run( ) { … while(done) { … try{ System.out.println("Type 'return/enter' key to continue and 'exit' to finish"); BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); String userInput=null; userInput = stdin.readLine(); if(userInput.compareTo("exit")==0) done=false; }catch(IOException iox2){ System.out.println("Exception..."+iox2); } counter++; } CS 667: 2. Multithreading Zlateva

More Related