Amity School of Engineering B.Tech., CSE(5 th Semester) Java Programming Topic: Multithreading ANIL SAROLIYA 1
Multitasking and Multithreading Multitasking refers to a computer's ability to perform multiple jobs concurrently More than one program are running concurrently Multitasking is done by two approach: Process Based Multitasking: Execution of more than one program concurrently. Programs are termed as heavyweight Tasks Thread Based Multitasking: Executing a program having more than one thread, performing different tasks simultaneously. Threads are termed as lightweight Tasks So, A thread is a single sequence of execution (or sequential flow of control) within a program Multithreading refers to multiple threads of control within a single program each program can run multiple threads of control within it e.g., Web Browser 2
Threads: Single Thread & Multiple Threads Single Thread: Single sequential flow of control Multiple Threads: Multiple sequential flow of control 3
Operating Systems to support multiple, concurrent paths of execution within a single process Example: MS-DOS Example: Java Runtime Environment One process, One Thread One process, Multiple thread Multiple process, One thread per process Multiple process, Multiple threads per process Example: Earlier versions of Unix OS Example: Windows, Solaris, and many modern versions of UNIX
Multi-threading: Definition CPU1 Thread 1 CPU2 Thread 2 CPU3 Thread 3 Multiple threads on multiple CPUs CPU Thread 1 Thread 2 Thread 3 Multiple threads sharing a single CPU Multithreading enables programs to have more than one execution paths(separate) which concurrently execute by a CPU. Each such path of the execution is a thread. Through multithreading operating system can achieve: Efficient utilization of system resources Such as maximum utilization of CPU cycles and minimizing idle time of CPU 5
Thread Versus Process 6
Threads Versus Processes (Continued.) In this model, the representation of a process includes: Its process control block User address space User and kernel stacks to manage the call/return behavior of the execution of the process While the process is running, it controls the processor registers. The contents of these registers are saved when the process is not running. 7
Threads Versus Processes (Continued.) In multithreaded environment, still a single PCB and user address space associated with the process, but it also include: separate stacks for each thread separate control block for each thread with: register values, priority values, and other thread-related state information Thus, all of the threads of a process share the state and resources of that process. They reside in the same address space and have access to the same data. When one thread alters an item of data in memory, other threads can see the results. If one thread opens a file with read privileges, other threads in the same process can also read from that file. 8
Threads versus Processes (Continued.) Threads share memory, processes don t. As compare to processes, threads are cheaper to create no need to copy memory Communication between threads is faster than between processes because of shared memory 9
Real Life Example General Example (My Thoughts): Relate the CPU like CAR In kitchen At Pani Poori shop Technical Example: MS Word Web Server Downloading Utilities IDM, DAP, etc 10
Java.lang.Thread Thread class belongs to java.lang package Threads are created as the instance of this class Thread class contains run() method Functionality of thread can only be achieved by overriding such run() method run() method is of void type Some constructors (remaining will be discussed in Runnable interface) are also defined in the Thread class. The constructors responsible for creating threads are: Thread ( ) //no arguments, means it uses default name & thread group Thread (String threadname) Thread (ThreadGroup threadgroup, String threadname) 11
The main thread When a Java program starts up, one thread begins running immediately. This is usually called the main thread of the program, because it is the one that is executed when the program begins. The main thread is important for two reasons: It is the thread from which other "child" threads will be spawned (produced). It must be the last thread to finish execution. When the main thread stops, your program terminates. Although the main thread is created automatically when your program is started, it can be controlled through a Thread object. The Thread object will hold the reference of the main thread with the help of currentthread() method of the Thread class 12
The main thread (continued ): Example Following code shows how main thread can be controlled in a program: public class MainThread { public static void main(string args [] ) { Thread t = Thread.currentThread ( ); //now main thread can be accessed via Thread object 't' System.out.println ("Current Thread : " + t); System.out.println ("Name : " + t.getname ( ) ); System.out.println (" "); t.setname ("New Thread"); System.out.println ("After changing name"); System.out.println ("Current Thread : " + t); System.out.println ("Name : " + t.getname ( ) ); System.out.println (" "); System.out.println ("This thread prints first 10 numbers"); try { for (int i=1; i<=10;i++) { System.out.print(i); System.out.print(" "); Thread.sleep(1000);//generates the one second delay catch (InterruptedException e) { System.out.println(e); 13
The main thread (continued ): output Output: Current Thread : Thread[main,5,main] Name : main After changing name Current Thread : Thread[New Thread,5,main] Name : New Thread This thread prints first 10 numbers 1 2 3 4 5 6 7 8 9 10 One second delay to display each number 14
Multithreading in Java Two ways to define a thread: 1. Extend Thread class and override the run method 2. Implement the run method of the Runnable interface (This is mostly used when the class implement this interface is derived from other class) Note: In both ways the run() method should be implemented To start a thread: Create a Thread object Call its start method 15
Creation of New Threads Extend the class from Thread Class. For example: public class HelloRunner extends Thread { //code Implement the Runnable interface. For example: class HelloRunner implements Runnable { //code 16
Creation of New Threads : By Inheriting the Thread Class Steps to be followed for thread creation: 1. Declare a class which is extending the Thread Class 2. Override the run() method, which forms the body of the thread 3. Create the thread object and use the start ( ) method to initiate the thread execution 17
Creation of New Threads : By Inheriting the Thread Class (Example) class ThreadOne extends Thread { public void run() { try { for(int j=1;j<5;j++) { System.out.println("\tFrom child thread 1: j=" +j); Thread.sleep(500); catch(interruptedexception e){ System.out.println("Child thread1 interrupted"); System.out.println("Exit from Child Thread 1"); class ThreadTwo extends Thread { public void run() { try { for(int k=1;k<5;k++) { System.out.println("\tFrom child thread 2: k=" +k); Thread.sleep(400); catch(interruptedexception e){ System.out.println("Child thread2 interrupted"); System.out.println("Exit from Child Thread 2"); 18
Creation of New Threads : By Inheriting the Thread Class (Example) (continued.) class ThreadThree extends Thread { public void run() { try { for(int i=1;i<5;i++) { System.out.println("\tFrom child thread 3: i=" +i); Thread.sleep(700); catch(interruptedexception e){ System.out.println("Child thread3 interrupted"); System.out.println("Exit from Child Thread 3"); public class ThreadDemo { public static void main(string[] args) { System.out.println("Main Thread Started"); ThreadOne a = new ThreadOne(); ThreadTwo b = new ThreadTwo(); ThreadThree c = new ThreadThree(); try{ a.start(); b.start(); c.start(); for(int m=1;m<=5;m++){ System.out.println("\tFrom Main Thread: m=" +m); Thread.sleep(900); catch (InterruptedException e){ System.out.println("Main interrupted"); System.out.println( \t\t\t\texit for main thread"); 19
Output: Creation of New Threads by Inheriting the Thread Class (Example) OUTPUT: java ThreadDemo Main Thread Started From child thread 1: j=1 From Main Thread: m=1 From child thread 2: k=1 From child thread 3: i=1 From child thread 2: k=2 From child thread 1: j=2 From child thread 3: i=2 From child thread 2: k=3 From Main Thread: m=2 From child thread 1: j=3 From child thread 2: k=4 From child thread 3: i=3 From child thread 1: j=4 Exit from Child Thread 2 From Main Thread: m=3 Exit from Child Thread 1 From child thread 3: i=4 From Main Thread: m=4 Exit from Child Thread 3 Exit for main thread 20
Creation of New Threads : By Implementing the Runnable Interface The Runnable interface should be implemented by any class whose instances are intended to be executed as a thread The class must define run() method of no arguments The run() method is like main() for the new thread Runnable is used when a class don t need to extends itself from Thread class Following constructors can be used while creating thread using Runnable interface: Thread(Runnable threadobj) Thread(Runnable threadobj, String threadname) Thread(ThreadGroup threadgroup, Runnable threadobj) Thread(ThreadGroup threadgroup, Runnable threadobj, String threadname) 21
Creation of New Threads : By Implementing the Runnable Interface (continued ) Two Ways of Starting a Thread For a class that implements Runnable 1. Caller thread creates Thread object and starts it explicitly after constructing the object of the class that implements Runnable interface. The start() method of the Thread object needs to be explicitly invoked after object instance is created 2. The Thread object is created and started within the constructor of the class that implements Runnable interface The caller thread just needs to create object instances of the Runnable class 22
Creation of New Threads : By Implementing the Runnable Interface (continued ) Example: Scheme 1: Caller thread creates a Thread object and starts it explicitly class PrintNameRunnable implements Runnable { String name; PrintNameRunnable(String name) { this.name = name; public void run() // Implementation of the run() defined in the Runnable interface. {try{ System.out.println("Thread "+name+" is executing at:"); for (int i = 0; i < 10; i++) { System.out.println(i+1+" time..."); Thread.sleep(500); catch(interruptedexception e){system.out.println("thread A interrupted"); public class RunnableThreadTest1 { public static void main(string args[]) { PrintNameRunnable pnt1 = new PrintNameRunnable("A"); Thread t1 = new Thread(pnt1); t1.start(); //new Thread(pnt1).start(); 23
Output: Scheme 1: Caller thread creates a Thread object and starts it explicitly OUTPUT: C:\>java RunnableThreadTest1 Thread A is executing at: 1 time... 2 time... 3 time... 4 time... 5 time... 6 time... 7 time... 8 time... 9 time... 10 time... 5 millisecond delay to display each number 24
Creation of New Threads : By Implementing the Runnable Interface (continued ) Example: Scheme 2: Thread object is created and started within a constructor class PrintNameRunnable implements Runnable { Thread thread; PrintNameRunnable(String name) { thread = new Thread(this, name); thread.start(); public void run() {try{ String name = thread.getname(); for (int i = 0; i < 10; i++) { System.out.println("Thread "+name+" is executing at"+(i+1)+" time.\n"); Thread.sleep(500); catch(interruptedexception e){system.out.println("thread A interrupted"); public class RunnableThreadTest2 { public static void main(string args[]) { new PrintNameRunnable("A"); new PrintNameRunnable("B"); new PrintNameRunnable("C"); 25
Output: Scheme 2: Thread object is created and started within a constructor.5 second delay to display each number OUTPUT: C:\>javac RunnableThreadTest2.java C:\>java RunnableThreadTest2 Thread A is executing at 1 time. Thread B is executing at 1 time. Thread C is executing at 1 time. Thread B is executing at 2 time. Thread C is executing at 2 time. Thread A is executing at 2 time. Thread B is executing at 3 time. Thread C is executing at 3 time. Thread A is executing at 3 time. Thread C is executing at 4 time. Thread A is executing at 4 time. Thread B is executing at 4 time. Thread A is executing at 5 time. Thread C is executing at 5 time. Thread B is executing at 5 time. Thread A is executing at 6 time. Thread B is executing at 6 time. Thread C is executing at 6 time. Thread A is executing at 7 time. Thread B is executing at 7 time. Thread C is executing at 7 time. Thread A is executing at 8 time. Thread B is executing at 8 time. Thread C is executing at 8 time. Thread C is executing at 9 time. Thread B is executing at 9 time. Thread A is executing at 9 time. Thread B is executing at 10 time. Thread C is executing at 10 time. Thread A is executing at 10 time. 26
Life Cycle of A Thread (Thread State in Java) Different states of a thread are : Programmer Scheduler Waiting/ Blocked start() stop() New Runnable Running Dead Yield() stop() New state After the creations of Thread instance the thread is in this state but before the start() method invocation. At this point, the thread is considered not alive. Runnable (Ready-to-run) state A thread start its life from Runnable state. A thread first enters runnable state after the invoking of start() method but a thread can return to this state after either running, waiting, sleeping or coming back from blocked state also. On this state a thread is waiting for a turn on the processor. yield() method is used to remain in this state. 27
Life Cycle of A Thread (contd ) Programmer Scheduler Waiting/ Blocked start() stop() New Runnable Running Dead Yield() stop() Running state - A thread is in running state that means the thread is currently executing. There are several ways to enter in Runnable state but there is only one way to enter in Running state: the scheduler select a thread from runnable pool (fully dependent to CPU scheduler). Dead state - A thread can be considered dead when its run() method completes. If any thread comes on this state that means it cannot ever run again. Blocked - A thread can enter in this state because of waiting the resources that are hold by another thread. wait(), sleep() and join() methods are used to achieve this state. 28
Thread Methods Method Return Type Description currentthread( ) Thread Returns an object reference to the thread in which it is invoked. setname( ) void Set the name of the thread object or instance. getname( ) String Retrieve the name of the thread object or instance. setpriority() void set the priority level of the thread object. Programmers can also uses three library defined constants as follows: setpriority(thread.min_priority), //min priority =1 setpriority(thread.norm_priority), //normal priority =5 setpriority(thread.max_priority) //maximum priority =10 getpriority() int Retrieve the priority value of the thread object or instance. start( ) void Start the thread by calling its run method. run( ) void This method is the entry point to execute thread, like the main method for applications. sleep( ) void Suspends a thread for a specified amount of time (in milliseconds). isalive( ) boolean This method is used to determine the thread is running or not. interrupt( ) void The method interrupt the threads on which it is invoked. yield( ) join( ) void void Causes the currently executing thread object to temporarily pause and allow other threads to execute. The join() method is called on the Thread object representing another thread. It tells the current thread to wait for the other thread to complete. 29
Waiting for (Joining) Therads : JoinDemo.java class CustomThread extends Thread{ CustomThread(String name) { super(name); this.start(); public void run() { try { for(int loop_index = 0; loop_index < 4; loop_index++) { System.out.println((Thread.currentThread()).getName()+ " thread here..."); Thread.sleep(1000); catch (InterruptedException e) { System.out.println((Thread.currentThread()).getName() +" ending."); class JoinDemo{ public static void main(string args[]) { CustomThread thread1 = new CustomThread("First"); CustomThread thread2 = new CustomThread("Second"); CustomThread thread3 = new CustomThread("Third"); CustomThread thread4 = new CustomThread("Fourth"); try{ thread1.join(); thread2.join(); thread3.join(); thread4.join(); catch (InterruptedException e) { 30
Output: Waiting for (Joining) Therads : JoinDemo.java OUTPUT: C:\>javac JoinDemo.java C:\>java JoinDemo Second thread here... Third thread here... First thread here... Fourth thread here... Second thread here... Fourth thread here... First thread here... Third thread here... Second thread here... Fourth thread here... First thread here... Third thread here... Second thread here... Fourth thread here... Third thread here... First thread here... Second ending. First ending. Third ending. Fourth ending. threads waiting for the other thread 31
Checking Whether a Thread Is Alive class CustomThread extends Thread{ CustomThread(String name) { super(name); this.start(); public void run() { try { for(int loop_index = 0; loop_index < 4; loop_index++) { System.out.println((Thread.currentThread()).getName()+ " thread here..."); Thread.sleep(1000); catch (InterruptedException e) { System.out.println((Thread.currentThread()).getName() +" ending."); class is AliveDemo{ public static void main(string args[]) { CustomThread thread1 = new CustomThread("First"); CustomThread thread2 = new CustomThread("Second"); CustomThread thread3 = new CustomThread("Third"); CustomThread thread4 = new CustomThread("Fourth"); System.out.println( Thread1 is Alive- +thread1.isalive()); try{ thread1.join(); thread2.join(); thread3.join(); thread4.join(); catch (InterruptedException e) { System.out.println( thread1.isalive()); 32
Output: Checking Whether a Thread Is Alive OUTPUT: C:\>javac isalivedemo.java C:\>java isalivedemo First thread here... Third thread here... Second thread here... Thread1 is Alive- true Fourth thread here... Third thread here... Fourth thread here... Second thread here... First thread here... Fourth thread here... First thread here... Third thread here... Second thread here... First thread here... Second thread here... Third thread here... Fourth thread here... First ending. Third ending. Fourth ending. Second ending. false At this point thread1 is not alive 33
Thread Priority When a Java thread is created, it inherits its priority from the thread that created it. You can also modify a thread's priority at any time after its creation using the setpriority method. Thread priorities are integers ranging between MIN_PRIORITY and MAX_PRIORITY (constants defined in the Thread class). The higher the integer, the higher the priority. At any given time, when multiple threads are ready to be executed, the runtime system chooses the runnable thread with the highest priority for execution. At any given time, the highest priority thread is running, but this is not guaranteed. For this reason, use priority only to affect scheduling policy for efficiency purposes. Do not rely on thread priority for algorithm correctness. 34
Thread Priority (continued ) In Java, each thread is assigned priority, which affects the order in which it is scheduled for running. The threads so far had same default priority (NORM_PRIORITY) and they are served using FCFS policy. Java allows users to change priority: ThreadName.setPriority(intNumber) MIN_PRIORITY = 1 NORM_PRIORITY=5 MAX_PRIORITY=10 35
Thread Priority Example: class A extends Thread { public void run() { System.out.println("Thread A started"); for(int i=1;i<=4;i++) { System.out.println("\t From ThreadA: i= "+i); System.out.println("Exit from A"); class B extends Thread { public void run() { System.out.println("Thread B started"); for(int j=1;j<=4;j++) { System.out.println("\t From ThreadB: j= "+j); System.out.println("Exit from B"); class C extends Thread { public void run() { System.out.println("Thread C started"); for(int k=1;k<=4;k++) { System.out.println("\t From ThreadC: k= "+k); System.out.println("Exit from C"); class ThreadPriority { public static void main(string args[]) { A threada = new A(); B threadb = new B(); C threadc = new C(); threadc.setpriority(thread.max_priority); threadb.setpriority(threada.getpriority()+1); threada.setpriority(thread.min_priority); System.out.println("Started Thread A"); threada.start(); System.out.println("Started Thread B"); threadb.start(); System.out.println("Started Thread C"); threadc.start(); System.out.println("End of main thread"); 36
Thread Synchronization Race condition Race conditions occur when multiple, asynchronously executing threads access the same object (called a shared resource) returning unexpected (wrong) results Example: Threads often need to share a common resource. i.e. a file, with one thread reading from the file while another thread writes to the file They can be avoided by synchronizing the threads which access the shared resource 37
Thread Synchronization : An Unsynchronized Example class TwoStrings { static void print(string str1, String str2) { System.out.print(str1); try {Thread.sleep(500); catch (InterruptedException ie) { System.out.println(str2); class PrintStringsThread implements Runnable { Thread thread; String str1, str2; PrintStringsThread(String str1, String str2) { this.str1 = str1; this.str2 = str2; //must be assign thread = new Thread(this); thread.start(); public void run() { TwoStrings.print(str1, str2); class TestThread { public static void main(string args[]) { new PrintStringsThread("Hello ", "there."); new PrintStringsThread("How are ", "you?"); new PrintStringsThread("Thank you, "very much!"); 38
Output: An Unsynchronized Example C:\>javac TestThread.java C:\>java TestThread Hello How are Thank youyou? there. very much! C:\>java TestThread How are Hello Thank youvery much! you? there. C:\>java TestThread How are Hello Thank youyou? there. very much! At each execution unsynchronized form of output will come C:\>java TestThread How are Thank youhello there. very much! you? 39
Thread Synchronization (continued.) When two or more threads try to access the same resource, they need some way to ensure that the resource will be used by only one thread at a time. The mechanism by which this is achieved is called synchronization. Key to synchronization is the concept of a monitor (or semaphore). A monitor is an object that is used as a mutually exclusive lock. 40
Thread Synchronization (continued.) Only one thread can own a monitor at one time. When a thread acquired a monitor it is said to have entered the monitor. All other threads attempting to enter the locked monitor are suspended until the first thread exits the monitor. These other threads are said to be waiting for the monitor. 41
Thread Synchronization using Java A thread becomes the owner of the object's monitor in one of two ways Option 1: Use synchronized method //used to synchronize the producer Syntax: class Xyz{ synchronized anymethod() {... //Method Body... Option 2: Use synchronized statement (or block) on a common object //used to synchronize the consumer Syntax: public void anyblock(){ synchronized (object of producer class){ //statement for the body of block 42
Thread Synchronization : A Synchronized Method Example class TwoStrings { synchronized static void print(string str1, String str2) { System.out.print(str1); try {Thread.sleep(500); catch (InterruptedException ie) { System.out.println(str2); class PrintStringsThread implements Runnable { Thread thread; String str1, str2; PrintStringsThread(String str1, String str2) { this.str1 = str1; this.str2 = str2; //must be assign thread = new Thread(this); thread.start(); public void run() { TwoStrings.print(str1, str2); class TestThread { public static void main(string args[]) { new PrintStringsThread("Hello ", "there."); new PrintStringsThread("How are ", "you?"); new PrintStringsThread("Thank you, "very much!"); 43
Output: Synchronized Method Example C:\>javac TestThread.java C:\>java TestThread Hello there. How are you? Thank youvery much! Synchronized form of output with delay of (.5 second in each string display) 44
Thread Synchronization : A Synchronized Block Example class TwoStrings { static void print(string str1, String str2) { System.out.print(str1); try {Thread.sleep(500); catch (InterruptedException ie) { System.out.println(str2); class PrintStringsThread implements Runnable { Thread thread; String str1, str2; TwoStrings ts; PrintStringsThread(String str1, String str2, TwoStrings ts) { this.str1 = str1; this.str2 = str2; this.ts=ts; //must be assign thread = new Thread(this); thread.start(); public void run() { synchronized (ts) //ts is passed because next statement is working as a consumer { ts.print(str1, str2); class TestThread { public static void main(string args[]) { TwoStrings ts = new TwoStrings(); new PrintStringsThread("Hello ", "there., ts); new PrintStringsThread("How are ", "you?, ts); new PrintStringsThread("Thank you, "very much!, ts); 45
Output: Synchronized Block Example C:\>javac TestThread.java C:\>java TestThread Hello there. How are you? Thank you very much! Synchronized form of output with delay of (.5 second in each string display) 46
Amity School of Engineering B.Tech., CSE(5th Sem.) Thanks 47