These points related to Day wise topic should be included : Prerequisites: Basic understanding of programming concepts such as variables, data types, loops, and conditionals. Familiarity with object-oriented programming (OOP) principles. Knowledge of concurrency and parallelism concepts in software development. Objectives: To introduce the concepts of multithreading and its importance in modern software development. To understand the lifecycle of a thread, including the various states a thread can be in. To explore thread priorities and their role in determining the order of execution in a multithreaded environment. Outcomes: Understanding of multithreading as a technique to improve program efficiency by executing multiple tasks concurrently. Proficiency in managing the lifecycle of threads, including transitioning between states such as new, runnable, blocked, waiting, timed waiting, and terminated. Knowledge of thread priorities and their impact on the scheduling of threads by the underlying operating system. Ability to design and implement multithreaded applications that leverage thread priorities to optimize resource utilization and improve performance.
Multithreading is a Java feature that allows concurrent execution of two or more parts of a program for maximum utilization of CPU. Each part of such program is called a thread. So, threads are light-weight processes within a process. Multithreading
Use of Multithreading • A multithreaded application performs two or more activities concurrently. It is accomplished by having each activity performed by a separate thread • Threads are the lightest tasks within a program, and they share memory space and resources with each other. Advantages of Java Multithreading It doesn't block the user because threads are independent and you can perform multiple operations at the same time. You can perform many operations together, so it saves time . Threads are independent , so it doesn't affect other threads if an exception occurs in a single thread.
Methods of Thread class: public void start(): starts the execution of the thread. JVM calls the run() method on the thread. public void run(): It is used to do an action for a thread. public void sleep(long miliseconds ): Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. public void join(): waits for a thread to die. public int getPriority (): returns the priority of the thread. public int setPriority ( int priority): changes the priority of the thread. Java provides Thread class to achieve thread programming. Thread class provides constructors and methods to create and perform operations on a thread. Thread class extends Object class and implements Runnable interface.
public String getName (): returns the name of the thread. public void setName (String name): changes the name of the thread. public Thread currentThread (): returns the reference of currently executing thread. public int getId (): returns the id of the thread. public int isAlive (): It tests if the thread is alive. public void yield(): causes the currently executing thread object to temporarily pause and allow other threads to execute.
public void suspend(): is used to suspend the thread public void resume(): is used to resume the suspended thread. public void stop(): is used to stop the thread public boolean isDaemon (): tests if the thread is a daemon thread. public void setDaemon ( boolean b): marks the thread as daemon or user thread. public void interrupt(): interrupts the thread. public boolean isInterrupted (): tests if the thread has been interrupted. public static boolean interrupted(): tests if the current thread has been interrupted.
A thread goes through various stages in its life cycle. For example, a thread is born, started, runs, and then dies. In Java, a thread always exists in any one of the following states. These states are: New Active Blocked / Waiting Timed Waiting Terminated Life Cycle of a Thread
New: Whenever a new thread is created, it is always in the new state. For a thread in the new state, the code has not been run yet and thus has not begun its execution. Active: When a thread invokes the start() method, it moves from the new state to the active state. The active state contains two states within it: one is runnable , and the other is running . Runnable: A thread, that is ready to run is then moved to the runnable state. In the runnable state, the thread may be running or may be ready to run at any given instant of time. It is the duty of the thread scheduler to provide the thread time to run, i.e., moving the thread the running state. A program implementing multithreading acquires a fixed slice of time to each individual thread. Each and every thread runs for a short span of time and when that allocated time slice is over, the thread voluntarily gives up the CPU to the other thread, so that the other threads can also run for their slice of time. Whenever such a scenario occurs, all those threads that are willing to run, waiting for their turn to run, lie in the runnable state. In the runnable state, there is a queue where the threads lie. Running: When the thread gets the CPU, it moves from the runnable to the running state. Generally, the most common change in the state of a thread is from runnable to running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time (not permanently) then, either the thread is in the blocked state or is in the waiting state. Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its name is A) has entered the critical section of a code and is not willing to leave that critical section. In such a scenario, another thread (its name is B) has to wait forever, which leads to starvation. To avoid such scenario, a timed waiting state is given to thread B. Thus, thread lies in the waiting state for a specific span of time, and not forever. A real example of timed waiting is when we invoke the sleep() method on a specific thread. The sleep() method puts the thread in the timed wait state. After the time runs out, the thread wakes up and start its execution from when it has left earlier. Terminated: A thread reaches the termination state because of the following reasons: When a thread has finished its job, then it exists or terminates normally. Abnormal termination: It occurs when some unusual events such as an unhandled exception or segmentation fault.
Advantages of a Multithreaded Application Improved performance and concurrency Simplified coding of remote procedure calls and conversations Simultaneous access to multiple applications Reduced number of required servers
Disadvantages of a Multithreaded Application Multithreaded applications present the following disadvantages: Difficulty of writing code Difficulty of debugging Difficulty of managing concurrency Difficulty of testing
There are two ways to create a thread: By extending Thread class By implementing Runnable interface. How to create thread
Thread class Thread class provide constructors and methods to create and perform operations on a thread. Thread class extends Object class and implements Runnable interface. Commonly used Constructors of Thread class: Thread() Thread(String name) Thread( Runnable r) Thread( Runnable r,String name)
Runnable interface: The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. Runnable interface have only one method named run(). public void run(): is used to perform action for a thread. Starting a thread: start() method of Thread class is used to start a newly created thread. It performs following tasks: A new thread starts(with new callstack ). The thread moves from New state to the Runnable state. When the thread gets a chance to execute, its target run() method will run.
1) Java Thread Example by extending Thread class class Multi extends Thread{ public void run(){ System.out.println ("thread is running..."); } public static void main(String args []){ Multi t1=new Multi(); t1.start(); } } Output: thread is running... Simple Thread Program
2) Java Thread Example by implementing Runnable interface class Multi3 implements Runnable { public void run(){ System.out.println ("thread is running..."); } public static void main(String args []){ Multi3 m1=new Multi3(); Thread t1 =new Thread(m1); t1.start(); } } Output: thread is running... Simple Thread Program
Priority of a Thread (Thread Priority) Each thread has a priority. Priorities are represented by a number between 1 and 10. In most cases, the thread scheduler schedules the threads according to their priority (known as preemptive scheduling). But it is not guaranteed because it depends on JVM specification that which scheduling it chooses. Note that not only JVM a Java programmer can also assign the priorities of a thread explicitly in a Java program.
Setter & Getter Method of Thread Priority Let's discuss the setter and getter method of the thread priority. public final int getPriority (): The java.lang.Thread.getPriority () method returns the priority of the given thread. public final void setPriority (int newPriority ): The java.lang.Thread.setPriority () method updates or assign the priority of the thread to newPriority . The method throws IllegalArgumentException if the value newPriority goes out of the range, which is 1 (minimum) to 10 (maximum).
3 constants defined in Thread class: public static int MIN_PRIORITY public static int NORM_PRIORITY public static int MAX_PRIORITY Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10.
Example of priority of a Thread: import java.lang .*; public class ThreadPriorityExample extends Thread { // Method 1 // Whenever the start() method is called by a thread // the run() method is invoked public void run() { // the print statement System.out.println ( "Inside the run() method" ); } // the main method public static void main(String argvs []) { // Creating threads with the help of ThreadPriorityExample class ThreadPriorityExample th1 = new ThreadPriorityExample (); ThreadPriorityExample th2 = new ThreadPriorityExample (); ThreadPriorityExample th3 = new ThreadPriorityExample ();
// We did not mention the priority of the thread. // Therefore, the priorities of the thread is 5, the default value // 1st Thread // Displaying the priority of the thread // using the getPriority () method System.out.println ( "Priority of the thread th1 is : " + th1.getPriority()); // 2nd Thread // Display the priority of the thread System.out.println ( "Priority of the thread th2 is : " + th2.getPriority()); // 3rd Thread // // Display the priority of the thread System.out.println ( "Priority of the thread th2 is : " + th2.getPriority()); // Setting priorities of above threads by // passing integer arguments th1.setPriority( 6 ); th2.setPriority( 3 ); th3.setPriority( 9 );
// 6 System.out.println ( "Priority of the thread th1 is : " + th1.getPriority()); // 3 System.out.println ( "Priority of the thread th2 is : " + th2.getPriority()); // 9 System.out.println ( "Priority of the thread th3 is : " + th3.getPriority()); // Main thread // Displaying name of the currently executing thread System.out.println ( "Currently Executing The Thread : " + Thread.currentThread (). getName ()); System.out.println ( "Priority of the main thread is : " + Thread.currentThread (). getPriority ()); // Priority of the main thread is 10 now Thread.currentThread (). setPriority ( 10 ); System.out.println ( "Priority of the main thread is : " + Thread.currentThread (). getPriority ()); } } Output: Priority of the thread th1 is : 5 Priority of the thread th2 is : 5 Priority of the thread th2 is : 5 Priority of the thread th1 is : 6 Priority of the thread th2 is : 3 Priority of the thread th3 is : 9 Currently Executing The Thread : main Priority of the main thread is : 5 Priority of the main thread is : 10
Placement Related Questions: What is multithreading, and why is it important in software development? How does it differ from traditional single-threaded programming? Can you explain the lifecycle of a thread in Java, including its various states and transitions between them? Discuss the significance of each state in the thread lifecycle (e.g., new, runnable, blocked, waiting, timed waiting, terminated). Can you provide examples of scenarios where threads transition between these states? Explain the concept of thread priority in Java. How is thread priority used to influence the scheduling of threads by the underlying operating system? What are the default thread priorities in Java, and how do they relate to the underlying operating system's scheduling policies? Discuss the factors to consider when assigning thread priorities in a multithreaded application. How does thread priority affect the fairness and responsiveness of thread execution? Can you describe the methods available in Java for setting and getting thread priorities? How would you use these methods in practice? Explain how thread priorities interact with the CPU scheduling algorithm to determine the order of execution in a multithreaded environment. Discuss the challenges associated with relying solely on thread priorities for controlling thread execution order. What are some alternative approaches to manage thread execution in complex applications? Describe a scenario where you would use multithreading with customized thread priorities to optimize the performance of a computational task. How would you design and implement this solution?