Unit 3
Unit 3
Exceptions
An exceptions is unaccepted/unwanted /abnormal situations that
occurs in runtime called exceptions.
Exception: An event that disrupts the normal flow of the program.
Error: A more severe issue (like running out of memory), generally not
meant to be handled by the program.
Types of Exceptions:
Checked Exceptions: These exceptions are checked at compile time.
You must either catch these exceptions or declare them using throws.
Example: IOException, SQLException.
Unchecked Exceptions: These are not checked at compile time. They
usually occur due to programming bugs. Example:
NullPointerException, ArrayIndexOutOfBoundsException.
try: Used to write code that may throw an exception.
catch: Used to handle exceptions.
finally: Always executed, useful for cleanup.
throw: In Java, the throw keyword is used to throw an exception. When
you want your program to intentionally raise an error (exception)
during execution, you use throw
throws: Declares exceptions in method signatures.
Example
public class ExceptionExample {
public static void main(String[] args) {
try {
int arithmetic = 10 / 0; // This will throw ArithmeticException
System.out.println(arithmetic);
} catch (ArithmeticException e) {
System.out.println("Exception caught: " + e);
} finally {
System.out.println("Closed security-related functions like
database connectivity.");
}
}
}
Example:
class ThrowThrowsExample {
// Method that declares an exception using 'throws'
static void checkAge(int age) throws ArithmeticException {
if (age < 18) {
throw new ArithmeticException("Access denied - You must be at
least 18 years old.");
} else {
System.out.println("Access granted - You are old enough.");
}
}
Example:
// Step 1: Create a custom exception class
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message); // Call the parent class constructor
}
}
New State
Runnable State
Blocked State
Waiting State
Timed Waiting State
Terminated State
New Thread: When a new thread is created, it is in the new state. The
thread has not yet started to run when the thread is in this state.
public static final Thread.State NEW
Runnable State: A thread that is ready to run is moved to a runnable
state. In this state, a thread might actually be running or it might be
ready to run at any instant of time.
public static final Thread.State RUNNABLE
Blocked: The thread will be in blocked state when it is trying to
acquire a lock but currently the lock is acquired by the other thread.
public static final Thread.State BLOCKED
Waiting state: The thread will be in waiting state when it calls wait()
method or join() method.
public static final Thread.State WAITING
Timed Waiting: A thread lies in a timed waiting state when it calls a
method with a time-out parameter.
Terminated State: A thread terminates because of either of the
following reasons:
Because it exits normally. This happens when the code of the thread
has been entirely executed by the program.
Because there occurred some unusual erroneous event, like a
segmentation fault or an unhandled exception.
t1.setName("Thread A");
t2.setName("Thread B");
Synchronization in Multithreading
In Java, Synchronization is a mechanism to control the access of
multiple threads to shared resources. It ensures that only one thread
can access a critical section of the code at a time, preventing race
conditions and ensuring data consistency.
Why is Synchronization Needed?
When multiple threads try to modify a shared resource
simultaneously, race conditions may occur, leading to unexpected
behavior and inconsistent data.
Types of Synchronization in Java
Synchronized Method
Synchronized Block
Static Synchronization
Example
class SharedResource {
synchronized void printTable(int num) { // Synchronized method
for (int i = 1; i <= 5; i++) {
System.out.println(num + " x " + i + " = " + (num * i));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
t1.start();
t2.start();
}
}
Daemon Thread vs Non-Daemon Thread in Java
Java threads can be categorized into Daemon Threads and Non-
Daemon Threads (also called User Threads). Let's explore the
differences and examples.
A Daemon Thread is a low-priority background thread that runs in the
background to support other user threads.
Important Rule: If all user threads finish execution, the JVM
automatically terminates daemon threads.
Characteristics of Daemon Threads:
Used for background tasks (e.g., Garbage Collector, Timer, etc.).
JVM automatically stops them when no user thread is running.
Not recommended for critical tasks (as they may stop unexpectedly).
What is a Non-Daemon (User) Thread?
A User Thread (Non-Daemon) is the default thread type in Java.
The JVM waits for all user threads to finish before terminating.
Example:
import java.io.FileInputStream;
import java.io.IOException;
Example 2
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
int byteData;
while ((byteData = fis.read()) != -1) {
fos.write(byteData);
}
System.out.println("File copied successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Example
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
// Writing to file
try (FileWriter writer = new FileWriter(fileName)) {
writer.write("Hello, this is a test file.\n");
writer.write("Writing and reading in the same file!");
System.out.println("✅ Data written to file successfully.");
} catch (IOException e) {
e.printStackTrace();
}
// Write to file
try (FileOutputStream fos = new FileOutputStream(filePath))
{
fos.write("Hello, Streams!".getBytes());
}
How It Works
Writer Thread → Writes data into a PipedOutputStream.
Reader Thread → Reads data from a PipedInputStream (connected to
the output stream).
Data flows like a pipeline from the writer to the reader.
Example:
import java.io.*;
// Start threads
writer.start();
reader.start();
}
}