0% found this document useful (0 votes)
35 views36 pages

Oopj Unit-4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views36 pages

Oopj Unit-4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.

Neelima

Object Oriented Programming Through JAVA


[B23CS2103]
Unit-IV
_______________________________________________________________________________________________________
SYLLABUS:
Exception Handling: Introduction, Hierarchy of Standard Exception Classes, Keywords
try, catch, throw, throws and finally Blocks, Multiple Catch Statements, Custom Exceptions,
Nested try and catch Blocks.
_______________________________________________________________________________________________________

Exception Handling

In programming, an exception is an unexpected event or error that occurs during the


execution of a program and disturbs its normal flow. In Java, exceptions are represented as
objects derived from the Throwable class. This system allows Java programs to handle
errors in a structured way, separating error-handling code from the main logic and
preventing sudden program termination.

How exceptions handled in Java?

In java, the exception handling mechanism uses five keywords namely try, catch, finally,
throw, and throws.

• try: A block of code that may throw an exception.


• catch: Handles specific exceptions thrown within the try block.
• throw: Used to explicitly throw an exception.
• throws: Declares exceptions that a method might throw.
• finally: Executes code after try-catch blocks, regardless of whether an exception
occurred.

In Java, exceptions are organized into a hierarchical structure, rooted in the Throwable
class. Understanding this hierarchy helps developers grasp the different types of errors,
their origins, and how to handle them effectively.

Hierarchy of Standard Exception Classes


The Throwable class is at the top of the exception hierarchy. This class is the superclass for
all errors and exceptions in Java. It has two main subclasses: Error and Exception.

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 1


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

1. Throwable Class

• The Throwable class is the root of the hierarchy. It provides methods like
printStackTrace(), getMessage(), and getCause() to retrieve details about the error.
All exceptions and errors are subclasses of Throwable.

2. Error Class

• Error represents simple problems that an application typically cannot recover from.
Errors are generated by the Java runtime environment and are not intended to be
caught or handled by the application. Some common subclasses of Error include:
o OutOfMemoryError: Thrown when the JVM runs out of memory.
o StackOverflowError: Thrown when there is a deep or infinite recursion
causing the stack to overflow.
o VirtualMachineError: Indicates a serious problem in the Java Virtual
Machine, such as InternalError.

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 2


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Examples of Errors

• StackOverflowError

public class StackOverflowExample


{
public static void main(String[] args)
{
recursiveMethod(); // Infinite recursion
}

public static void recursiveMethod()


{
recursiveMethod(); // Calls itself endlessly
}
}

Explanation: This program leads to a StackOverflowError due to the infinite recursion in


recursiveMethod.

• OutOfMemoryError

import java.util.ArrayList;

public class OutOfMemoryExample {


public static void main(String[] args) {
ArrayList<int[]> list = new ArrayList<>();
while (true) {
list.add(new int[1000000]); // Allocate large chunks of memory
}
}
}

Explanation: This code continuously allocates large memory chunks until it runs out of
memory, triggering an OutOfMemoryError.

3. Exception Class

The Exception class represents conditions that an application might want to catch.
Exceptions can be divided into two main categories: checked and unchecked exceptions.

Types of Exceptions in Java

Java exceptions divided into two primary categories: checked exceptions and unchecked
exceptions.

1. Checked Exceptions

• Definition: Checked exceptions are compile-time exceptions; they must be either


handled in the code using a try-catch block or declared in the method signature with

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 3


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

the throws keyword. The compiler checks for these exceptions, ensuring they are
handled.
• Use Case: These exceptions are typically caused by external conditions (e.g., file I/O,
database access) and are often outside the programmer’s control.

Examples of Checked Exceptions

1. IOException (Input/Output Exception)

Occurs when there’s a failure in input or output operations, such as reading from a file
that doesn’t exist.

Example:

import java.io.FileReader;
import java.io.IOException;
public class IOExceptionExample
{
public static void main(String[] args)
{
try
{
FileReader file = new FileReader("nonexistentfile.txt");
}
catch (IOException e)
{
System.out.println("File not found or cannot be opened: " + e.getMessage());
}
}
}

Explanation: Attempting to open a nonexistent file throws an IOException. This checked


exception is handled in a try-catch block.

2. SQLException (SQL Exception)

Thrown when there is an issue with accessing or interacting with a database.

Example:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SQLExceptionExample


{
public static void main(String[] args)
{
try
{

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 4


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Connection conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/nonexistentdb",
"user", "password");
}
catch (SQLException e)
{
System.out.println("Database access error: " + e.getMessage());
}
}
}

Explanation: Attempting to connect to a nonexistent database throws a SQLException, a


checked exception.

3. ClassNotFoundException

This exception occurs when the application tries to load a class that is not found in the
classpath.

Example:

public class ClassNotFoundExceptionExample


{
public static void main(String[] args)
{
try
{
Class.forName("com.example.NonExistentClass");
}
catch (ClassNotFoundException e)
{
System.out.println("Class not found: " + e.getMessage());
}
}
}

Explanation: The Class.forName() method attempts to load a class by name, which is


missing here, resulting in a ClassNotFoundException. This checked exception is handled in
a try-catch block.

2. Unchecked Exceptions

• Definition: Unchecked exceptions, also called runtime exceptions, are exceptions


that occur during program execution and are not checked at compile time. The
compiler doesn’t require these exceptions to be handled explicitly.
• Use Case: Unchecked exceptions usually result from programming errors, such as
accessing an invalid array index or a null object.

Examples of Unchecked Exceptions

1. ArithmeticException

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 5


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Thrown when an illegal arithmetic operation is performed, like division by zero.

Example:

public class ArithmeticExceptionExample


{
public static void main(String[] args)
{
try
{
int result = 10 / 0;
}
catch (ArithmeticException e)
{
System.out.println("Cannot divide by zero: " + e.getMessage());
}
}
}

Explanation: Dividing 10 by 0 throws an ArithmeticException, an unchecked exception.

2. NullPointerException

Thrown when there’s an attempt to use an object reference that has not been initialized.

Example:

public class NullPointerExceptionExample {


public static void main(String[] args) {
String text = null;
try {
System.out.println(text.length());
} catch (NullPointerException e) {
System.out.println("Null reference encountered: " + e.getMessage());
}
}
}

Explanation: Since text is null, calling length() on it causes a NullPointerException.

3. ArrayIndexOutOfBoundsException

Thrown when accessing an array element with an invalid index.

Example:

public class ArrayIndexOutOfBoundsExceptionExample


{
public static void main(String[] args)
{
int[] numbers = {1, 2, 3};

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 6


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

try
{
System.out.println(numbers[3]);
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Array index out of bounds: " + e.getMessage());
}
}
}

Explanation: Attempting to access numbers[3] results in an


ArrayIndexOutOfBoundsException.

4. NumberFormatException

Thrown when an attempt is made to convert a string into a numeric type but the string
doesn’t contain a valid format.

Example:

public class NumberFormatExceptionExample


{
public static void main(String[] args)
{
String number = "abc";
try
{
int result = Integer.parseInt(number);
}
catch (NumberFormatException e)
{
System.out.println("Invalid number format: " + e.getMessage());
}
}
}

Explanation: The string "abc" cannot be converted into an integer, so it throws a


NumberFormatException, an unchecked exception.

Comparison of Checked vs. Unchecked Exceptions


Feature Checked Exception Unchecked Exception
Checked at
Yes No
Compile-Time
Requires Yes (try-catch or throws
No (optional handling)
Handling keyword)
ArithmeticException,
IOException,
Common Types NullPointerException,
ClassNotFoundException
NumberFormatException
Typical Causes External conditions (e.g., file I/O) Programming errors (e.g., null

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 7


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Feature Checked Exception Unchecked Exception


reference)
SQLException,
Example ArrayIndexOutOfBoundsException
FileNotFoundException

In Java, the exception-handling mechanism revolves around five key components: try,
catch, throw, throws, and finally. Each of these plays a unique role in managing and
recovering from exceptions in a structured way.

1. try Block

The try block is used to wrap a segment of code that might throw an exception. When an
exception occurs within a try block, Java jumps out of the try block and looks for a
corresponding catch block to handle the exception.

Example:

public class TryExample


{
public static void main(String[] args)
{
try
{
int data = 10 / 0; // This will throw an ArithmeticException
System.out.println("This line will not execute");
}
catch (ArithmeticException e)
{
System.out.println("Cannot divide by zero.");
}
}
}

Explanation: Here, an ArithmeticException occurs in the try block (division by zero). The
program control transfers to the catch block, and the message "Cannot divide by zero." is
displayed. The System.out.println line within the try block is skipped.

2. catch Block

The catch block is used to handle exceptions that are thrown in the associated try block.
Each catch block specifies the type of exception it can handle, and multiple catch blocks
can be used to handle different exception types.

Example:

public class CatchExample


{
public static void main(String[] args)
{

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 8


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

try
{
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // this throw ArrayIndexOutOfBoundsException
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Index is out of bounds!");
}
}
}

Explanation: An ArrayIndexOutOfBoundsException is thrown, and the catch block


catches it. If we had other types of exceptions, like a NullPointerException, we could add
additional catch blocks to handle them specifically.

3. throw Statement

The throw keyword is used to explicitly throw an exception from within a method or block
of code. This is useful when you want to create custom error conditions or trigger
exceptions manually.

Syntax:

throw new ExceptionType("Error Message");

Example:

public class ThrowExample


{
public static void main(String[] args)
{
try
{
checkAge(15); // This will throw an IllegalArgumentException
}
catch (IllegalArgumentException e)
{
System.out.println(e.getMessage());
}
}

public static void checkAge(int age)


{
if (age < 18)
{
throw new IllegalArgumentException("Age must be at least 18.");
}
}
}

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 9


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Explanation: Here, the checkAge method uses throw to create a new


IllegalArgumentException if age is less than 18. The exception is then caught in the main
method, and the message "Age must be at least 18." is printed.

4. throws Clause

The throws clause is used in a method’s signature to declare the types of exceptions that a
method might throw. This informs any calling method that it should handle or further
declare the exception.

Syntax:

public void methodName() throws ExceptionType1, ExceptionType2


{
// method code
}

Example:

import java.io.FileReader;
import java.io.IOException;
public class ThrowsExample
{
public static void main(String[] args)
{
try
{
readFile();
}
catch (IOException e)
{
System.out.println("File not found or cannot be opened.");
}
}

public static void readFile() throws IOException


{
FileReader file = new FileReader("nonexistentfile.txt");
}
}

Explanation: The readFile method declares throws IOException, meaning that it might
throw an IOException. Since this exception is declared but not handled in readFile, it is
caught in the main method where readFile is called.

5. finally Block

The finally block is always executed after the try and catch blocks, regardless of whether
an exception was thrown or caught. This block is used for cleanup activities, like closing a
file or releasing resources.

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 10


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Example:

import java.io.FileInputStream;
import java.io.IOException;

public class FinallyExample {


public static void main(String[] args) {
FileInputStream file = null;
try {
file = new FileInputStream("sample.txt");
System.out.println("File opened successfully.");
} catch (IOException e) {
System.out.println("File not found or cannot be opened.");
} finally {
if (file != null) {
try {
file.close();
System.out.println("File closed successfully.");
} catch (IOException e) {
System.out.println("Error while closing the file.");
}
}
}
}
}

Explanation: Here, the finally block is used to ensure the file is closed regardless of
whether an exception occurs in the try block. This is essential for resource management,
ensuring that resources are released even if an error occurs.

Difference between throw and throws

Basis of throw throws


Differences
Definition Java throw keyword is used Java throws keyword is used in
throw an exception explicitly in the method signature to declare
the code, inside the function or an exception which might be
the block of code. thrown by the function while the
execution of the code.
Usage Type of exception Using throw Using throws keyword, we can
keyword, we can only declare both checked and
propagate unchecked unchecked exceptions. However,
exception i.e., the checked the throws keyword can be used
exception cannot be to propagate checked exceptions
propagated using throw only. only.
Syntax The throw keyword is followed The throws keyword is followed
by an instance of Exception to by class names of Exceptions to
be thrown. be thrown.
Declaration throw is used within the throws is used with the method
method. signature.

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 11


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Internal We are allowed to throw only We can declare multiple


implementation one exception at a time i.e. we exceptions using throws
cannot throw multiple keyword that can be thrown by
exceptions. the method. For example, main()
throws IOException,
SQLException.

Multiple Catch Statements

In Java, multiple catch statements allow a program to handle different types of exceptions
separately, based on the specific exception that occurs. Each catch block handles a specific
exception type, providing a more controlled and detailed response to different errors. This
is useful in cases where multiple exceptions might be thrown by the same try block, and
each needs a unique handling approach.

Syntax for Multiple Catch Statements


try {
// Code that may throw multiple types of exceptions
} catch (ExceptionType1 e1) {
// Handle ExceptionType1
} catch (ExceptionType2 e2) {
// Handle ExceptionType2
} catch (ExceptionType3 e3) {
// Handle ExceptionType3
}
// More catch blocks can be added if needed

In this structure:

• The try block wraps the code that may throw one or more exceptions.
• Each catch block follows the try block and catches a specific exception type.
• If an exception occurs, the control is transferred to the corresponding catch block
that matches the exception type.

Example of Multiple Catch Statements

public class MultipleCatchExample {


public static void main(String[] args) {
try {
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // Throws ArrayIndexOutOfBoundsException

int result = 10 / 0; // Throws ArithmeticException

} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Array index is out of bounds.");
} catch (ArithmeticException e) {
System.out.println("Error: Cannot divide by zero.");
} catch (Exception e) {

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 12


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

System.out.println("General exception caught: " + e);


}
}
}

Explanation:

1. ArrayIndexOutOfBoundsException: The first statement in the try block tries to


access an invalid array index. This will trigger the
ArrayIndexOutOfBoundsException catch block.
2. ArithmeticException: If the first statement is commented out or fixed, the second
statement (10 / 0) would throw an ArithmeticException, which is handled by the
second catch block.
3. General Exception: If any other exception occurs that isn't specifically caught by
previous catch blocks, the final catch block for Exception will handle it.

Catch Multiple Exceptions in a Single Block

In Java 7 and later, multiple exceptions can also be caught in a single catch block by
separating each exception type with a pipe | symbol. This approach is useful for handling
different exceptions with the same code block, reducing code redundancy.

Example of Catching Multiple Exceptions in a Single Block:

public class MultiCatchExample {


public static void main(String[] args) {
try {
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // Throws ArrayIndexOutOfBoundsException

int result = 10 / 0; // Throws ArithmeticException

} catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {


System.out.println("Error: Either an array index issue or division by zero
occurred.");
} catch (Exception e) {
System.out.println("General exception caught: " + e);
}
}
}

Explanation: Here, ArrayIndexOutOfBoundsException and ArithmeticException are both


caught in a single catch block because they use the same handling code. If either of these
exceptions is thrown, the message "Error: Either an array index issue or division by zero
occurred." is displayed.

Custom Exceptions

Custom exceptions in Java are user-defined exceptions created to represent specific error
conditions in an application. When the standard Java exception classes (such as IOException
or NullPointerException) don’t adequately capture the nature of a problem, custom

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 13


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

exceptions provide a way to create a specialized exception that can make the code easier to
understand, debug, and maintain.

Why Use Custom Exceptions?

Custom exceptions are useful for:

1. Providing meaningful error messages: They make errors easier to interpret by


naming the exception according to its purpose (e.g., InvalidAgeException).
2. Adding specific logic: Custom exceptions can include additional information or
methods to handle unique error conditions.
3. Supporting application-specific error handling: They represent errors specific to
the application's domain, like InsufficientBalanceException for a banking
application.

Creating a Custom Exception

To create a custom exception:

1. Define a class that extends the Exception class (for checked exceptions) or the
RuntimeException class (for unchecked exceptions).
2. Implement a constructor that takes an error message or any other parameters as
needed.
3. Optionally, override methods like toString() to provide a custom string
representation of the exception.

Types of Custom Exceptions

• Checked Custom Exceptions: Extends Exception. These must be handled (using


try-catch or throws).
• Unchecked Custom Exceptions: Extends RuntimeException. These do not require
explicit handling at compile-time but can be handled if needed.

Example: Checked Custom Exception

Let’s create a custom exception named InvalidAgeException that will be thrown if a user’s
age is below a required threshold.

// Custom checked exception by extending Exception


class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message); // Call to superclass (Exception) constructor
}
}

public class CustomExceptionExample {


public static void main(String[] args) {
try {
checkAge(15); // Call method that may throw InvalidAgeException
} catch (InvalidAgeException e) {
System.out.println("Exception caught: " + e.getMessage());

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 14


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

}
}

// Method that throws InvalidAgeException if age is below 18


public static void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException(" .");
}
System.out.println("Age is valid.");
}
}

Explanation:

1. InvalidAgeException: This class extends Exception to create a checked exception.


The constructor takes a message parameter, which is passed to the superclass
constructor (Exception) to set the exception message.
2. checkAge Method: Checks if age is less than 18. If true, it throws
InvalidAgeException, stopping further execution in checkAge.
3. Handling: The InvalidAgeException is caught in the catch block in main, displaying
the message "Age must be at least 18."

Example: Unchecked Custom Exception

For an unchecked exception, let’s create InvalidInputException that throws an error if a


given input is negative.

// Custom unchecked exception by extending RuntimeException


class InvalidInputException extends RuntimeException {
public InvalidInputException(String message) {
super(message);
}
}

public class UncheckedCustomExceptionExample {


public static void main(String[] args) {
try {
processInput(-5); // This will throw InvalidInputException
} catch (InvalidInputException e) {
System.out.println("Exception caught: " + e.getMessage());
}
}

// Method that throws InvalidInputException if input is negative


public static void processInput(int input) {
if (input < 0) {
throw new InvalidInputException("Input cannot be negative.");
}
System.out.println("Processing input: " + input);
}
}

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 15


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Explanation:

1. InvalidInputException: This class extends RuntimeException, making it unchecked.


The exception message is set by calling the superclass constructor with message.
2. processInput Method: Throws InvalidInputException if input is negative.
3. Handling: Even though this is an unchecked exception, it’s caught in the catch block
in main.

Benefits of Custom Exceptions

1. Improved Readability: Code becomes easier to understand, as custom exception


names explain specific error types.
2. Domain-Specific Error Handling: Tailored error messages and fields provide more
relevant information.
3. Better Debugging: Including additional fields and methods provides more context,
making it easier to locate and fix issues.

Best Practices for Custom Exceptions

• Naming Conventions: Use names that end with "Exception" to make it clear they
are exception classes.
• Use Meaningful Messages: Include informative error messages to clarify what
went wrong.
• Minimize Unchecked Custom Exceptions: Only use unchecked custom exceptions
for runtime conditions that the program generally won’t recover from.
• Document Custom Exceptions: Clearly document custom exceptions for
developers, as they are specific to the application.

Custom exceptions make error-handling code more in-built and tailored to the needs of
specific applications, enhancing maintainability and debugging.

Nested try-catch Blocks

Nested try and catch blocks allow Java developers to handle exceptions that occur within a
specific portion of code, especially when multiple layers of exception handling are needed.
A try block can contain another try-catch block within it, which is useful when an inner code
block may throw an exception that is handled specifically by an inner catch block, while the
outer try-catch structure handles exceptions that arise from a broader scope.

Purpose of Nested try-catch Blocks

• Specific Exception Handling: They allow different levels of handling for exceptions,
from specific cases in the inner block to more general exceptions in the outer block.
• Preventing Program Termination: They allow the program to handle exceptions
at multiple levels without terminating abruptly.
• Organized Error Management: Useful when some exceptions need to be handled
locally within a specific part of the code, while others need more generalized
handling.

Syntax for Nested try-catch Blocks


try {

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 16


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

// Outer try block


try {
// Inner try block
} catch (SpecificExceptionType e) {
// Inner catch block for specific exceptions
}
} catch (GeneralExceptionType e) {
// Outer catch block for more general exceptions
}

Example of Nested try-catch Blocks

Here’s an example of a nested try-catch block. The inner try block handles specific
exceptions related to array indexing, while the outer try block catches any arithmetic issues.

public class NestedTryCatchExample {


public static void main(String[] args) {
try {
int[] numbers = {1, 2, 3};

try {
// Attempt to access an invalid index
System.out.println(numbers[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Inner catch: Array index out of bounds.");
}

// Outer try block statement that can cause an ArithmeticException


int result = 10 / 0;
System.out.println("Result: " + result);

} catch (ArithmeticException e) {
System.out.println("Outer catch: Cannot divide by zero.");
} finally {
System.out.println("Finally block: Cleanup actions here.");
}
}
}

Explanation:

1. Inner try-catch Block: Attempts to access an invalid index in numbers. When this
causes an ArrayIndexOutOfBoundsException, the inner catch block handles it with
a specific message.
2. Outer try-catch Block: After the inner block executes, an ArithmeticException is
triggered by dividing by zero (10 / 0). The outer catch block catches and handles
this exception.
3. Finally Block: Runs cleanup code regardless of whether an exception occurred.

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 17


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Output:

Inner catch: Array index out of bounds.


Outer catch: Cannot divide by zero.
Finally block: Cleanup actions here.

Example with More Levels of Nesting

In some cases, multiple layers of nesting can be used for very specific error handling.

public class MultipleNestedTryCatch {


public static void main(String[] args) {
try {
int[] arr = {1, 2, 3};
int num = 5, denom = 0;

try {
System.out.println("Trying to divide by zero:");
int result = num / denom;
} catch (ArithmeticException e) {
System.out.println("Innermost catch: Division by zero error.");
}

try {
System.out.println("Accessing an invalid array index:");
System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Inner catch: Array index out of bounds.");
}

} catch (Exception e) {
System.out.println("Outer catch: General exception caught.");
}
}
}

Explanation:

1. Innermost try-catch handles division by zero with an ArithmeticException.


2. Inner try-catch deals with an invalid array index in arr, caught by
ArrayIndexOutOfBoundsException.
3. Outer catch is a catch-all for any other Exception that may occur in the outer try
block.

Points to Remember with Nested try-catch

1. Exception Propagation: If an exception isn’t caught by any inner catch blocks, it


propagates to the outer catch block.
2. Readability: Overuse of nested try-catch blocks can make code complex, so it’s
best used only when specific parts of the code require unique error handling.

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 18


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

3. Performance Impact: Nested exception handling can have a slight impact on


performance due to the multiple layers, though this is usually minimal.

Common Use Cases

1. File Processing: Attempting to read/write to files within an inner try block and
catching IO-related exceptions while handling more generic errors (e.g.,
FileNotFoundException) in the outer block.
2. Database Operations: Nesting can handle database connection errors in the outer
try-catch block and specific query-related exceptions in the inner block.
3. Complex Calculations: For applications with multiple potential exception types
(e.g., array, arithmetic), nested try-catch can allow for handling distinct issues
independently.

Nested try-catch blocks help manage complex error conditions by enabling targeted
exception handling at various levels, leading to more organized and maintainable code.

************

AIM & CIC Sagi Rama Krishnam Raju Engineering College(A) 19


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Object Oriented Programming through JAVA


UNIT -IV - PART - 2
_______________________________________________________________________________________________________
SYLLABUS:
Multithreaded Programming: Introduction, Thread Life Cycle, Extending Thread class,
Implementing Runnable interface, Thread Priorities, Thread Synchronization.
_______________________________________________________________________________________________________

Multitasking is the ability of a computer or operating system to execute multiple tasks or


processes seemingly at the same time. It enables users to run more than one application,
program, or task concurrently, making efficient use of CPU resources.

A process is an instance of a program that is currently executing. It includes the program


code, data, and system resources that are required for the program to run. When you run
an application on your computer, such as a web browser or text editor, the operating system
creates a process for it.

Multithreaded Programming: Introduction

Multithreaded programming is a technique that enables the concurrent execution of


multiple tasks within a single application. This approach helps make efficient use of system
resources, particularly in multi-core processors, by dividing tasks into smaller units
(threads) that can run simultaneously. It’s widely used to improve responsiveness,
performance, and resource sharing within applications.

What is a Thread?

• A thread is the smallest unit of execution in a program. Threads within a program


can run independently, allowing multiple tasks to occur concurrently within the
same application.
• Characteristics:
o Lightweight: Threads are considered lightweight because they share the
same memory and resources within a process, making context switching
between threads faster than between processes.
o Execution Path: Each thread represents a unique path of execution within a
program.

What is Multithreading?

• Multithreading is the capability of a program to create multiple threads within a


single process. Each thread can run independently, performing different tasks or
parts of a task concurrently.
• Purpose: Multithreading allows a program to handle multiple operations
simultaneously, which enhances performance and keeps applications responsive.
• Use Case Example:
o In a web browser, one thread could manage user input, while another
thread loads new data, allowing smooth browsing without delays.

CIC Sagi Rama Krishnam Raju Engineering College(A) 1


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Differences between Multithreading and Multitasking


Feature Multithreading Multitasking
Running multiple threads within a Running multiple independent
Definition
single process processes simultaneously
Operates at the operating system
Scope Operates within a single application
level
Memory Threads share the same memory space Each process has its own memory
Usage within a process and resources
System Lower overhead, faster context Higher overhead, as each process
Overhead switching within threads requires memory allocation
Threads are not isolated; they share Processes are isolated from one
Isolation
resources another
Performing multiple tasks within an Running multiple applications
Common
application (e.g., UI and background (e.g., browser and text editor
Use Case
operations in one app) simultaneously)
Failure Issues in one thread can impact other Failure in one process generally
Impact threads in the same process doesn’t affect others

Examples in Real Life

1. Multithreading Example:
o Gaming Application: Different threads can handle rendering graphics,
processing user input, and managing background sound.
o Web Server: A server might use a new thread for each client request,
enabling multiple requests to be handled concurrently within the same
server application.
2. Multitasking Example:
o Operating System: Running a browser, a text editor, and a music player
simultaneously.
o Background Services: A system may have antivirus software, file syncing
applications, and other services running in the background as separate
processes.

In Java, multithreading can be achieved in two primary ways:

1. Extending the Thread Class


2. Implementing the Runnable Interface

Each approach has its own benefits and is chosen based on specific use cases. Let’s go
through a deep explanation of each method, how they differ, and when to use them.

1. Extending the Thread Class

When a class extends the Thread class, it inherits all its methods and properties. In this
approach, we create a new class that directly extends Thread, and then override its run()
method to define the code that will be executed when the thread starts.

CIC Sagi Rama Krishnam Raju Engineering College(A) 2


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Key Points

• When extending Thread, each instance of the class represents a new thread.
• The start() method (inherited from the Thread class) is called to begin execution of
the new thread. Internally, start() invokes the run() method, which contains the
thread’s task.
• Because Java doesn’t support multiple inheritance, if a class extends Thread, it
cannot extend any other class. This is a significant limitation and one of the reasons
why implementing Runnable is often preferred.

Steps to Create a Thread by Extending the Thread Class

1. Define a class that extends the Thread class.


2. Override the run() method with the code that should execute in the new thread.
3. Create an instance of this subclass and call its start() method to launch the thread.

Example: Creating a Thread by Extending the Thread Class

// Step 1: Extend the Thread class


class MyThread extends Thread {
// Step 2: Override the run() method
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread by extending Thread class: " + i);
try {
Thread.sleep(500); // Sleep for 500 ms
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}

public class Main {


public static void main(String[] args) {
// Step 3: Create an instance of MyThread and start the thread
MyThread t1 = new MyThread();
t1.start(); // This will invoke run() method in MyThread
}
}

In this example, MyThread class extends Thread, and the run() method contains the task
to be performed by this thread. When t1.start() is called, it internally calls the run()
method, executing the task in a new thread.

Advantages of Extending the Thread Class

• Simpler syntax since there’s no need to explicitly create a Runnable object.


• The class gains direct access to Thread methods (such as getId() and getName()),
which can be handy if thread management features are needed.

CIC Sagi Rama Krishnam Raju Engineering College(A) 3


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Disadvantages of Extending the Thread Class

• Inflexibility: Since Java only allows single inheritance, extending Thread restricts
the ability to extend another class.
• Tight coupling: By inheriting from Thread, the task’s code is tightly coupled to
thread management code, which reduces flexibility and reusability.

2. Implementing the Runnable Interface

An alternative way to create a thread is by implementing the Runnable interface. Runnable


is a functional interface with a single run() method. When using this approach, we define
the thread’s behavior in the run() method but do not directly extend the Thread class.

Key Points

• The Runnable interface is implemented by a class that defines the thread’s


behavior.
• We pass an instance of the Runnable class to a Thread object, then call start() on
the Thread instance to begin execution.
• This method promotes better design and reusability because implementing
Runnable decouples the thread’s behavior from its instantiation and allows the
class to extend other classes.

Steps to Create a Thread by Implementing the Runnable Interface

1. Define a class that implements the Runnable interface.


2. Implement the run() method with the code to execute in the new thread.
3. Create an instance of Thread, passing the Runnable instance as an argument.
4. Call the start() method on the Thread instance.

Example: Creating a Thread by Implementing the Runnable Interface

// Step 1: Implement the Runnable interface


class MyRunnable implements Runnable {
// Step 2: Override the run() method
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread by implementing Runnable interface: " + i);
try {
Thread.sleep(500); // Sleep for 500 ms
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}

public class Main {


public static void main(String[] args) {
// Step 3: Create an instance of MyRunnable and pass it to a new Thread
MyRunnable myRunnable = new MyRunnable();

CIC Sagi Rama Krishnam Raju Engineering College(A) 4


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Thread t1 = new Thread(myRunnable); // Step 4: Start the thread


t1.start(); // This will invoke run() method in MyRunnable
}
}

In this example, MyRunnable implements Runnable, and the task is defined in its run()
method. A Thread object is created by passing the Runnable object as an argument, then
start() is called on the Thread instance.

Advantages of Implementing the Runnable Interface

• Flexibility: Allows the class to extend another class, which is more flexible in
complex applications.
• Decoupling: The task code (defined in run()) is separate from thread
management, making the design more modular and promoting reusability.
• Resource Efficiency: Allows sharing a single Runnable instance between multiple
threads if needed.

Disadvantages of Implementing the Runnable Interface

• Less direct access to Thread methods: Since it doesn’t extend Thread, we have to
use Thread.currentThread() to access thread-specific methods.

Example for Multiple Classes using Multithreading :

// Thread that prints numbers from 1 to 5


class NumberThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("NumberThread: " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println("NumberThread finished execution.");
}
}
// Thread that prints characters from 'A' to 'E'
class CharacterThread extends Thread {
@Override
public void run() {
for (char c = 'A'; c <= 'E'; c++) {
System.out.println("CharacterThread: " + c);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}

CIC Sagi Rama Krishnam Raju Engineering College(A) 5


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

}
System.out.println("CharacterThread finished execution.");
}
}
// Thread that prints a custom message five times
class MessageThread extends Thread {
private String message;

public MessageThread(String message) {


this.message = message;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("MessageThread: " + message);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println("MessageThread finished execution.");
}
}

public class MultiThreadDemo {


public static void main(String[] args) {
// Creating instances of each thread
NumberThread numberThread = new NumberThread();
CharacterThread characterThread = new CharacterThread();
MessageThread messageThread = new MessageThread("Hello, Multithreading!");
// Starting each thread
numberThread.start();
characterThread.start();
messageThread.start();
}
}

CIC Sagi Rama Krishnam Raju Engineering College(A) 6


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Thread Life Cycle in Java

1. Newborn (New):

• When a thread is created using the new keyword but has not yet started, it is in the
Newborn or New state.
• A thread in this state is not active or running.
• Transition:
o The thread moves to the Runnable state when the start() method is called.

2. Runnable:

• In the Runnable state, the thread is ready to run but may not be actively running.
• It is waiting for CPU time to execute. The Java scheduler determines which thread
runs based on thread priority and other factors.
• Transitions:
o To Running: When the CPU assigns time to the thread, it enters the
Running state.
o To Blocked: If yield() is called, the thread may yield control to another
thread, returning to the Runnable state.

3. Running:

• A thread is in the Running state when it is actively executing its run() method.
• This is where the actual processing takes place.
• Transition:
o To Runnable: The yield() method allows the thread to re-enter the
Runnable state, giving other threads a chance to execute.
o To Blocked: If the thread calls sleep(), wait(), or suspend(), it transitions to
the Blocked state.

CIC Sagi Rama Krishnam Raju Engineering College(A) 7


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

4. Blocked:

• In the Blocked state, the thread is temporarily inactive. It is waiting for some
condition to be met before it can continue running.
• This state occurs due to methods like sleep(t), wait(), or suspend().
• Transitions:
o To Runnable: When the thread receives a notify(), notifyAll(), or resume()
signal, or the sleep time ends, it returns to the Runnable state.

5. Dead:

• The thread reaches the Dead state once it has completed execution or if it was
terminated prematurely by the stop() method.
• A thread in this state cannot be restarted or brought back to life.
• Transition:
o A thread moves to the Dead state after the stop() method is called or when
it finishes executing the run() method.

Summary of Methods and Transitions:

• start(): Moves the thread from Newborn to Runnable.


• yield(): Moves the thread from Running to Runnable, allowing other threads to
run.
• sleep(t), wait(), suspend(): Moves the thread from Running or Runnable to
Blocked.
• notify(), resume(): Moves the thread from Blocked to Runnable.
• stop(): Moves the thread to Dead, terminating it permanently.

• The stop() method is deprecated due to potential issues with releasing resources
abruptly, so it is generally avoided in modern Java applications.
• The Java scheduler determines which thread will enter the Running state when
multiple threads are in the Runnable state, typically based on priority or other
system-specific factors.

Thread Priorities in Java

Java threads have priorities that help the scheduler decide the order in which threads are
scheduled for execution. Each thread has a priority between MIN_PRIORITY (1) and
MAX_PRIORITY (10), with NORM_PRIORITY (5) as the default.

Higher-priority threads are generally scheduled before lower-priority threads. However,


thread priority does not guarantee exact scheduling order, as it depends on the thread
scheduler implementation by the JVM and OS.

Setting Thread Priority

To set a thread's priority, use the setPriority(int priority) method, where priority is an
integer between 1 and 10.

class MyThread extends Thread {


public void run() {

CIC Sagi Rama Krishnam Raju Engineering College(A) 8


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

System.out.println(Thread.currentThread().getName() + " with priority " +


Thread.currentThread().getPriority());
}
}

public class ThreadPriorityExample {


public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();

t1.setPriority(Thread.MIN_PRIORITY); // Set priority to 1


t2.setPriority(Thread.NORM_PRIORITY); // Set priority to 5 (default)
t3.setPriority(Thread.MAX_PRIORITY); // Set priority to 10

t1.start();
t2.start();
t3.start();
}
}

In this example:

• t1 has MIN_PRIORITY.
• t2 has NORM_PRIORITY.
• t3 has MAX_PRIORITY.

Since t3 has the highest priority, it is more likely to execute before t1 and t2. However,
this behavior may vary due to JVM scheduling.

Thread Synchronization in Java

Thread Synchronization is essential for managing access to shared resources in multi-


threaded programs. Without synchronization, two or more threads could access shared
data at the same time, leading to data inconsistency.

Java provides multiple mechanisms for synchronizing threads:

1. Synchronized Method
2. Synchronized Block
3. Static Synchronization

1. Synchronized Method

A synchronized method locks the object for any other synchronized method on the same
object, allowing only one thread to execute at a time.

Example: Bank Account with Synchronized Deposit

class BankAccount extends Thread {


private static int balance = 0;

CIC Sagi Rama Krishnam Raju Engineering College(A) 9


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

// Synchronized deposit method to ensure thread-safe updates


public synchronized void deposit(int amount) {
balance += amount;
System.out.println(Thread.currentThread().getName() + " deposited " + amount
+ ". Balance: " + balance);
}

private int amount;

// Constructor to initialize the deposit amount for each thread


public BankAccount(int amount) {
this.amount = amount;
}

@Override
public void run() {
for (int i = 0; i < 5; i++) {
deposit(amount); // Calls the synchronized deposit method
}
}
}

public class SynchronizedMethodExample {


public static void main(String[] args) {
// Creating two threads with different deposit amounts
BankAccount t1 = new BankAccount(100);
BankAccount t2 = new BankAccount(50);

// Setting thread names for identification


t1.setName("Thread-1");
t2.setName("Thread-2");

// Starting the threads


t1.start();
t2.start();
}
}
In this example, deposit is synchronized. This ensures that when one thread is executing
deposit, no other thread can access this method on the same account object, avoiding
inconsistencies in the balance.

Example – 2

class IRCTCBooking extends Thread {


private static int availableTickets = 4; // Total tickets available
private String passengerName;

public IRCTCBooking(String passengerName) {


this.passengerName = passengerName;
}

CIC Sagi Rama Krishnam Raju Engineering College(A) 10


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

// Synchronized method to prevent multiple threads from booking the same ticket
public synchronized void bookTicket() {
if (availableTickets > 0) {
System.out.println(passengerName + " successfully booked a ticket. Tickets left:
" + --availableTickets);
} else {
System.out.println("Sorry, " + passengerName + ". Tickets are sold out.");
}
}

@Override
public void run() {
bookTicket();
}
}

// Separate class with the main method


public class BookingSystem {
public static void main(String[] args) {
// Creating 5 passenger threads, trying to book tickets
IRCTCBooking passenger1 = new IRCTCBooking("Passenger 1");
IRCTCBooking passenger2 = new IRCTCBooking("Passenger 2");
IRCTCBooking passenger3 = new IRCTCBooking("Passenger 3");
IRCTCBooking passenger4 = new IRCTCBooking("Passenger 4");
IRCTCBooking passenger5 = new IRCTCBooking("Passenger 5");
IRCTCBooking passenger6 = new IRCTCBooking("Passenger 6");

// Starting all threads


passenger1.start();
passenger2.start();
passenger3.start();
passenger4.start();
passenger5.start();
passenger6.start();
}
}

2. Synchronized Block

A synchronized block limits the scope of synchronization, locking only the specified
section of code. This is useful for minimizing the locking overhead.

Example: Synchronized Block in Account Withdrawal

class BankAccount {
private int balance = 1000;

public void withdraw(int amount) {


synchronized (this) {
if (balance >= amount) {

CIC Sagi Rama Krishnam Raju Engineering College(A) 11


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

balance -= amount;
System.out.println(Thread.currentThread().getName() + " withdrew " +
amount + ". Balance: " + balance);
} else {
System.out.println("Insufficient funds for " +
Thread.currentThread().getName());
}
}
}

public int getBalance() {


return balance;
}
}

public class SynchronizedBlockExample {


public static void main(String[] args) {
BankAccount account = new BankAccount();

Thread t1 = new Thread(() -> account.withdraw(500), "Thread-1");


Thread t2 = new Thread(() -> account.withdraw(700), "Thread-2");

t1.start();
t2.start();
}
}

In this example, only the withdrawal logic is synchronized, reducing the time that the lock
is held.

Example 2 : IRCTC BOOKING

class IRCTCBooking extends Thread {


private static int availableTickets = 3; // Total tickets available
private String passengerName;

public IRCTCBooking(String passengerName) {


this.passengerName = passengerName;
}

public void bookTicket() {


// Synchronize only the critical section that modifies availableTickets
synchronized (IRCTCBooking.class) {
if (availableTickets > 0) {
System.out.println(passengerName + " successfully booked a ticket. Tickets
left: " + --availableTickets);
} else {
System.out.println("Sorry, " + passengerName + ". Tickets are sold out.");
}
}
}

CIC Sagi Rama Krishnam Raju Engineering College(A) 12


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

@Override
public void run() {
bookTicket();
}
}

public class BookingSystemOne {


public static void main(String[] args) {
// Creating 5 passenger threads, trying to book tickets
IRCTCBooking passenger1 = new IRCTCBooking("Passenger 1");
IRCTCBooking passenger2 = new IRCTCBooking("Passenger 2");
IRCTCBooking passenger3 = new IRCTCBooking("Passenger 3");
IRCTCBooking passenger4 = new IRCTCBooking("Passenger 4");
IRCTCBooking passenger5 = new IRCTCBooking("Passenger 5");

// Starting all threads


passenger1.start();
passenger2.start();
passenger3.start();
passenger4.start();
passenger5.start();
}
}

3. Static Synchronization

Static synchronization locks the class rather than an instance, meaning only one thread
can execute any synchronized static method in the class at a time.

Example: Static Synchronized Counter

class Counter {
private static int count = 0;

public static synchronized void increment() {


count++;
System.out.println(Thread.currentThread().getName() + " incremented count to
" + count);
}

public static int getCount() {


return count;
}
}

public class StaticSynchronizationExample {


public static void main(String[] args) {
Thread t1 = new Thread(Counter::increment, "Thread-1");
Thread t2 = new Thread(Counter::increment, "Thread-2");

CIC Sagi Rama Krishnam Raju Engineering College(A) 13


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

t1.start();
t2.start();
}
}

Here, increment is a static synchronized method, ensuring that only one thread can access
this method across all instances of Counter.

Thread Synchronization with Locks

The ReentrantLock class provides more control over thread synchronization, allowing
features such as fairness policy, re-entrant locking, and timed waits.

import java.util.concurrent.locks.ReentrantLock;

class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();

public void sharedResource() {


lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " is accessing shared
resource");
} finally {
lock.unlock();
}
}
}

public class LockExample {


public static void main(String[] args) {
ReentrantLockExample example = new ReentrantLockExample();

Thread t1 = new Thread(example::sharedResource, "Thread-1");


Thread t2 = new Thread(example::sharedResource, "Thread-2");

t1.start();
t2.start();
}
}

In this example:

• lock.lock() is used to acquire the lock, and lock.unlock() releases it.


• ReentrantLock allows more flexibility, such as trying to acquire the lock with a
timeout, checking if the lock is held, etc.

Thread Methods

Method Description
start() Starts a new thread and calls the run() method of the thread,

CIC Sagi Rama Krishnam Raju Engineering College(A) 14


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Method Description
placing it in the runnable state.
Contains the code that defines the task of the thread. It should be
run() overridden when implementing a new thread, but it does not start
the thread itself.
Pauses the execution of the current thread for the specified
sleep(long millis) number of milliseconds, allowing other threads to execute. Throws
InterruptedException.
Waits for the thread to complete execution before proceeding with
join()
the code following it in the calling thread.
Waits for a thread to finish or for the specified timeout to expire.
join(long millis)
This is useful to ensure threads finish within a certain time limit.
Temporarily pauses the execution of the current thread, giving
yield()
other threads of equal priority a chance to execute.
Interrupts a thread, setting its interrupt status to true. If the
interrupt()
thread is blocked, it will throw an InterruptedException.
Checks if the thread has been interrupted, returning true if the
isInterrupted()
thread is in the interrupted state.
Sets the priority of the thread to the specified integer value (1 to
setPriority(int
10). Higher priorities increase the likelihood of the thread being
priority)
scheduled earlier.
getPriority() Returns the priority of the thread.
setName(String
Changes the name of the thread to the specified string value.
name)
getName() Returns the name of the thread.
Checks if the thread is still running, returning true if the thread is
isAlive()
alive (i.e., started and not terminated).
currentThread() Returns a reference to the currently executing thread.
getId() Returns a unique identifier for the thread.
Marks the thread as a daemon thread (background thread).
setDaemon(boolean
Daemon threads terminate when all non-daemon threads have
on)
finished.
isDaemon() Checks if the thread is a daemon thread, returning true if it is.
Returns the current state of the thread (e.g., NEW, RUNNABLE,
getState()
BLOCKED, WAITING, TIMED_WAITING, TERMINATED).
Causes the current thread to wait until another thread calls
wait() notify() or notifyAll() on the same object. Must be called in a
synchronized context.
Wakes up one waiting thread on the same object. Must be called in
notify()
a synchronized context.
Wakes up all threads waiting on the same object. Must be called in
notifyAll()
a synchronized context.

This table provides a concise overview of thread methods, highlighting their functionality
and typical usage.

CIC Sagi Rama Krishnam Raju Engineering College(A) 15


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

Here's a Java program demonstrating several key thread methods, including start(), run(),
sleep(), join(), setPriority(), interrupt(), isInterrupted(), getState(), and isAlive().

This program creates three threads with different priorities, demonstrates sleep and join
methods, and showcases how to handle interruptions.

class MyThread extends Thread {

public MyThread(String name) {


super(name); // Set the name of the thread
}
@Override
public void run() {
try {
System.out.println(getName() + " is starting with priority " + getPriority());

for (int i = 0; i < 3; i++) {


System.out.println(getName() + " is running... Iteration: " + i);

// Put the thread to sleep for 500ms


Thread.sleep(500);

// Demonstrate interrupt handling


if (Thread.interrupted()) {
System.out.println(getName() + " was interrupted!");
return; // Exit the loop if interrupted
}
}
System.out.println(getName() + " has finished executing.");
} catch (InterruptedException e) {
System.out.println(getName() + " was interrupted during sleep!");
}
}
}

public class ThreadMethodsDemo {


public static void main(String[] args) {
// Create three threads
MyThread t1 = new MyThread("Thread-1");
MyThread t2 = new MyThread("Thread-2");
MyThread t3 = new MyThread("Thread-3");
// Set priorities for demonstration
t1.setPriority(Thread.MIN_PRIORITY); // 1
t2.setPriority(Thread.NORM_PRIORITY); // 5
t3.setPriority(Thread.MAX_PRIORITY); // 10

// Start the threads


t1.start();
t2.start();
t3.start();

CIC Sagi Rama Krishnam Raju Engineering College(A) 16


Object Oriented Programming Through JAVA[B23CS2103] Ch Raghuram & A.Neelima

// Wait for the threads to complete


try {
// Check if threads are alive
System.out.println(t1.getName() + " isAlive: " + t1.isAlive());
System.out.println(t2.getName() + " isAlive: " + t2.isAlive());
System.out.println(t3.getName() + " isAlive: " + t3.isAlive());

// Join threads to wait for their completion


t1.join();
t2.join();
t3.join();
System.out.println("All threads have finished execution.");

} catch (InterruptedException e) {
System.out.println("Main thread interrupted!");
}
// Interrupt one of the threads if it is still running
if (t1.isAlive()) {
System.out.println("Interrupting " + t1.getName());
t1.interrupt();
}
}
}
Explanation of Methods Used

1. start(): Starts each thread, invoking their run() methods.


2. run(): Defines the task each thread will execute, printing a message for each
iteration.
3. sleep(): Puts each thread to sleep for 500ms during each iteration.
4. interrupt(): Used to interrupt t1 if it’s still alive after join().
5. isAlive(): Checks if each thread is still running before and after join().
6. setPriority(int priority): Sets each thread's priority.
7. getPriority(): Fetches and displays the priority of each thread.
8. join(): Main thread waits for all three threads to complete before printing a
completion message.
9. isInterrupted(): Checks if the thread has been interrupted during its execution in
run().

This example shows how to control thread execution and manage interruption gracefully,
providing output on each thread's activity and its final state.

***********

CIC Sagi Rama Krishnam Raju Engineering College(A) 17

You might also like