0% found this document useful (0 votes)
16 views30 pages

Unit 4 and 5

Uploaded by

gurly101
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)
16 views30 pages

Unit 4 and 5

Uploaded by

gurly101
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/ 30

1.

File Handling in Java


File handling in Java provides the ability to read, write, and manipulate files. It is part of the
java.io package and includes classes like File, FileReader, FileWriter, and BufferedReader.

Key Classes for File Handling:


File: Represents file and directory pathnames.
FileReader and FileWriter: For reading and writing character files.
BufferedReader: Reads text from an input stream, buffering characters for efficiency.
FileInputStream and FileOutputStream: For reading and writing binary files.
Example 1: Creating and Writing to a File
import java.io.*;

public class FileWriteExample {


public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("example.txt");
writer.write("Hello, this is a test file.");
writer.close();
System.out.println("File written successfully.");
} catch (IOException e) {
System.out.println("An error occurred: " + e.getMessage());
}
}
}
Example 2: Reading from a File
import java.io.*;

public class FileReadExample {


public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new FileReader("example.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (IOException e) {
System.out.println("An error occurred: " + e.getMessage());
}
}
}
2. Basic GUI Elements
Java's Swing library provides tools for creating graphical user interfaces. Swing components are
part of the javax.swing package.
Common GUI Elements:
JFrame: A top-level container that represents a window.
JButton: A button component.
JLabel: A component for displaying text or images.
JTextField: A field to input text.
JTextArea: A multi-line area to display/edit text.
Example: Basic GUI Application
import javax.swing.*;

public class BasicGUI {


public static void main(String[] args) {
JFrame frame = new JFrame("Basic GUI");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JLabel label = new JLabel("Enter your name:");


JTextField textField = new JTextField(20);
JButton button = new JButton("Submit");
JLabel outputLabel = new JLabel("");

button.addActionListener(e -> outputLabel.setText("Hello, " + textField.getText()));

JPanel panel = new JPanel();


panel.add(label);
panel.add(textField);
panel.add(button);
panel.add(outputLabel);

frame.add(panel);
frame.setVisible(true);
}
}
3. Event Delegation Model

The Event Delegation Model in Java is a design pattern for handling events like button clicks or
mouse movements. It consists of:

Event Source: The component (e.g., JButton) that generates the event.
Event Listener: The object that listens for and handles the event.
Event Object: Encapsulates information about the event (e.g., ActionEvent for button clicks).
Steps in the Event Delegation Model:
Register a Listener: Attach a listener to the source using methods like addActionListener.
Event Occurs: The source generates an event object.
Listener Handles the Event: The event object is passed to the listener's handler method (e.g.,
actionPerformed).
4. Event Handling
Event handling involves writing code to define what happens when an event occurs.

Example: Handling Button Clicks


import javax.swing.*;
import java.awt.event.*;

public class EventHandlingExample {


public static void main(String[] args) {
JFrame frame = new JFrame("Event Handling Example");
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton button = new JButton("Click Me");


JLabel label = new JLabel("");
// Adding ActionListener to handle button click
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
label.setText("Button was clicked!");
}
});

JPanel panel = new JPanel();


panel.add(button);
panel.add(label);

frame.add(panel);
frame.setVisible(true);
}
}
Handling Mouse Events
Mouse events include actions like clicks, movements, and releases. The MouseListener
interface is used for handling these.

Example: Handling Mouse Events

import javax.swing.*;
import java.awt.event.*;

public class MouseEventExample {


public static void main(String[] args) {
JFrame frame = new JFrame("Mouse Event Example");
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JLabel label = new JLabel("Move or click the mouse.");

frame.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
label.setText("Mouse clicked at: " + e.getX() + ", " + e.getY());
}

public void mouseEntered(MouseEvent e) {


label.setText("Mouse entered the frame.");
}
});

frame.add(label);
frame.setVisible(true);
}
}
Summary of Key Concepts:
File Handling: Use classes like File, FileReader, and FileWriter for working with files.
Basic GUI Elements: Swing components like JButton, JLabel, JTextField for building user
interfaces.
Event Delegation Model: Separates event generation (source) from handling (listener).
Event Handling: Use interfaces like ActionListener and MouseListener to define behavior for
specific events.

Detailed Explanation of Event Handling in Java


Event handling in Java is a mechanism for responding to user interactions with graphical user
interface (GUI) components such as buttons, checkboxes, or mouse movements. It follows the
Event Delegation Model, which separates the event source (e.g., a button) from the event
handling logic (e.g., the response to a click).

Key Components of Event Handling


1. Event Source
The component (like JButton, JTextField) that generates an event.
Example: A button generates an ActionEvent when clicked.
2. Event Object
Encapsulates information about the event.
Subclasses of java.util.EventObject, such as:
ActionEvent: For button clicks.
MouseEvent: For mouse actions like clicks and movements.
KeyEvent: For keyboard actions.
WindowEvent: For window actions like closing or resizing.
3. Event Listener
An interface that contains methods for handling specific events.
Must be implemented by a class to listen for and handle events.
Example listeners:
ActionListener: For handling button clicks.
MouseListener: For mouse actions.
KeyListener: For keyboard actions.
4. Event Handler
The code written inside the listener's method to define the event's response.
Example: Updating a label when a button is clicked.
Steps to Implement Event Handling
Step 1: Import Required Packages
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Step 2: Create a GUI Component
Example: Create a JButton to act as the event source.
Step 3: Implement an Event Listener
Write a class or method that implements the appropriate listener interface.
Step 4: Register the Listener
Use methods like addActionListener, addMouseListener, etc., to attach the listener to the
source.
Step 5: Handle the Event
Write logic inside the listener's method to specify the action upon event occurrence.
Types of Listeners and Their Methods
1. ActionListener
Handles action events like button clicks or menu item selection.
Method: void actionPerformed(ActionEvent e)
Example: Button Click Handling

import javax.swing.*;
import java.awt.event.*;

public class ActionListenerExample {


public static void main(String[] args) {
JFrame frame = new JFrame("ActionListener Example");
JButton button = new JButton("Click Me");
JLabel label = new JLabel("");

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
label.setText("Button Clicked!");
}
});

frame.setLayout(new FlowLayout());
frame.add(button);
frame.add(label);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
2. MouseListener
Handles mouse events like clicks, movements, and entering or exiting a component.
Methods:
mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
Example: Mouse Click Handling

import javax.swing.*;
import java.awt.event.*;

public class MouseListenerExample {


public static void main(String[] args) {
JFrame frame = new JFrame("MouseListener Example");
JLabel label = new JLabel("Click anywhere inside the frame.");

frame.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
label.setText("Mouse clicked at: " + e.getX() + ", " + e.getY());
}
});

frame.add(label);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
3. KeyListener
Handles keyboard events like key presses or releases.
Methods:
keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
Example: Key Press Handling

import javax.swing.*;
import java.awt.event.*;

public class KeyListenerExample {


public static void main(String[] args) {
JFrame frame = new JFrame("KeyListener Example");
JTextField textField = new JTextField(20);
JLabel label = new JLabel("");

textField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
label.setText("Key typed: " + e.getKeyChar());
}
});

frame.setLayout(new FlowLayout());
frame.add(textField);
frame.add(label);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
4. WindowListener
Handles window events like opening, closing, or minimizing.
Methods:
windowOpened(WindowEvent e)
windowClosing(WindowEvent e)
windowClosed(WindowEvent e)
windowIconified(WindowEvent e)
windowDeiconified(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
Example: Window Close Handling

import javax.swing.*;
import java.awt.event.*;

public class WindowListenerExample {


public static void main(String[] args) {
JFrame frame = new JFrame("WindowListener Example");

frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("Window is closing");
System.exit(0);
}
});

frame.setSize(400, 300);
frame.setVisible(true);
}
}
Event Handling Using Lambda Expressions (Java 8+)
Java 8 introduced lambda expressions, which simplify event handling by removing the need for
anonymous inner classes.
Example: Button Click Handling with Lambda

import javax.swing.*;

public class LambdaEventHandling {


public static void main(String[] args) {
JFrame frame = new JFrame("Lambda Event Handling");
JButton button = new JButton("Click Me");
JLabel label = new JLabel("");

button.addActionListener(e -> label.setText("Button clicked using Lambda!"));

frame.setLayout(new FlowLayout());
frame.add(button);
frame.add(label);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Key Points About Event Handling
Anonymous Inner Classes:
Simplify handling by allowing event listeners to be defined inline.
Adapter Classes:
For interfaces with multiple methods, adapter classes like MouseAdapter or KeyAdapter can be
used to override only the necessary methods.
Lambda Expressions:
Provide a concise way to handle events in Java 8 and later.
Event handling is a critical part of building responsive and interactive applications. By

😊
understanding these concepts, developers can create robust GUI-based applications in Java.
Let me know if you need more examples or further clarifications!

Graphical User Interface (GUI) Elements in Java


GUI elements, also known as components, are the building blocks of a user interface in Java.
Java provides several libraries for creating GUIs, with Swing being one of the most popular
frameworks.

Basic GUI Elements


1. JFrame
The main window where components are added.
It is a top-level container.
Common Methods:
setSize(int width, int height): Sets the size of the window.
setTitle(String title): Sets the title of the frame.
setDefaultCloseOperation(int operation): Determines the close operation.
setVisible(boolean visible): Displays the frame.
Example:

import javax.swing.*;

public class JFrameExample {


public static void main(String[] args) {
JFrame frame = new JFrame("My JFrame");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
2. JLabel
Used to display text or images.
Cannot be edited by the user.
Example:

import javax.swing.*;

public class JLabelExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JLabel Example");
JLabel label = new JLabel("Hello, JLabel!");
frame.add(label);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
3. JButton
A clickable button component.
Often used with ActionListener to handle button clicks.
Example:

import javax.swing.*;
import java.awt.event.*;

public class JButtonExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JButton Example");
JButton button = new JButton("Click Me");
JLabel label = new JLabel("");
button.addActionListener(e -> label.setText("Button Clicked!"));

frame.setLayout(new FlowLayout());
frame.add(button);
frame.add(label);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
4. JTextField
A single-line text input component.
Example:

import javax.swing.*;

public class JTextFieldExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JTextField Example");
JTextField textField = new JTextField(20);
JButton button = new JButton("Submit");
JLabel label = new JLabel("");

button.addActionListener(e -> label.setText("Entered: " + textField.getText()));

frame.setLayout(new FlowLayout());
frame.add(textField);
frame.add(button);
frame.add(label);
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
5. JTextArea
A multi-line text input component.
Example:

import javax.swing.*;

public class JTextAreaExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JTextArea Example");
JTextArea textArea = new JTextArea(10, 30);
JButton button = new JButton("Submit");
JLabel label = new JLabel("");

button.addActionListener(e -> label.setText("You entered: " + textArea.getText()));

frame.setLayout(new FlowLayout());
frame.add(new JScrollPane(textArea)); // Adds a scroll bar
frame.add(button);
frame.add(label);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
6. JCheckBox
A box that can be checked or unchecked to represent a choice.
Example:

import javax.swing.*;

public class JCheckBoxExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JCheckBox Example");
JCheckBox box1 = new JCheckBox("Option 1");
JCheckBox box2 = new JCheckBox("Option 2");
JButton button = new JButton("Check");

button.addActionListener(e -> {
if (box1.isSelected()) System.out.println("Option 1 selected");
if (box2.isSelected()) System.out.println("Option 2 selected");
});

frame.setLayout(new FlowLayout());
frame.add(box1);
frame.add(box2);
frame.add(button);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
7. JRadioButton
Represents one choice in a group where only one option can be selected at a time.
Example:

import javax.swing.*;

public class JRadioButtonExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JRadioButton Example");
JRadioButton rb1 = new JRadioButton("Male");
JRadioButton rb2 = new JRadioButton("Female");
ButtonGroup group = new ButtonGroup(); // Ensures only one selection
group.add(rb1);
group.add(rb2);

JButton button = new JButton("Submit");


JLabel label = new JLabel("");

button.addActionListener(e -> {
if (rb1.isSelected()) label.setText("Male selected");
if (rb2.isSelected()) label.setText("Female selected");
});

frame.setLayout(new FlowLayout());
frame.add(rb1);
frame.add(rb2);
frame.add(button);
frame.add(label);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Scheduling in Java
Scheduling determines how threads are managed and executed by the CPU. Java uses a
priority-based scheduling model where threads with higher priorities are more likely to execute
first. The actual behavior of thread scheduling depends on the JVM and underlying operating
system.

Key Concepts in Thread Scheduling


Thread Priority:

Every thread has a priority value, ranging from 1 (minimum) to 10 (maximum).


Default priority is 5.
Set using setPriority(int priority).
Example:
Thread t1 = new Thread(() -> System.out.println("Thread 1"));
t1.setPriority(Thread.MAX_PRIORITY); // Priority 10
Thread States:

New: Thread is created but not started.


Runnable: Thread is ready to run but waiting for CPU time.
Running: Thread is actively executing.
Waiting/Blocked: Thread is waiting for resources or conditions.
Terminated: Thread has completed execution.
Time-Slicing:

Threads share CPU time in small slices, giving the appearance of concurrency.
Thread Scheduling Example
Example: Using Priorities

public class ThreadPriorityExample {


public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1");
}
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 5; i++) {
System.out.println("Thread 2");
}
});

t1.setPriority(Thread.MIN_PRIORITY); // Priority 1
t2.setPriority(Thread.MAX_PRIORITY); // Priority 10

t1.start();
t2.start();
}
}
Thread Yield
A thread can voluntarily release the CPU using Thread.yield(), allowing other threads of equal
priority to execute.
Example:

public class ThreadYieldExample {


public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 executing");
Thread.yield(); // Yield CPU to another thread
}
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 5; i++) {
System.out.println("Thread 2 executing");
}
});

t1.start();
t2.start();
}
}
Thread Sleep
A thread can pause its execution for a specific period using Thread.sleep(milliseconds).
Example:

public class ThreadSleepExample {


public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
System.out.println("Thread 1 sleeping");
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});

t1.start();
}
}
Summary
GUI Elements: Provide interactivity and visualization in applications using components like
JButton, JTextField, etc.
Scheduling: Determines how threads execute, influenced by priorities, sleep, and yield
mechanisms.
Let me know if you'd like more in-depth examples or explanations!
Detailed Explanation: Exceptions and Multithreading in Java

1. Exceptions in Java

Need for Exceptions

1. Definition: An exception is an event that disrupts the normal flow of a program.


2. Why Needed:
○ To handle runtime errors (e.g., division by zero, file not found).
○ Prevent program crashes by catching and handling errors.
○ Improve code robustness and reliability.
○ Separate error-handling logic from normal logic.

Types of Exceptions

1. Checked Exceptions:

○ Exceptions checked at compile time.


○ Must be declared using throws or handled with try-catch.
○ Examples: IOException, SQLException.
2. Unchecked Exceptions:

○ Exceptions not checked at compile time.


○ Occur during runtime.
○ Examples: NullPointerException, ArrayIndexOutOfBoundsException.

Checked vs. Unchecked Exceptions


Feature Checked Exception Unchecked Exception

Compile-Time Yes No
Check

Declaration Must be handled or declared using Optional to handle or declare.


throws.

Examples IOException, ArithmeticException,


FileNotFoundException NullPointerException

Occurs When Anticipated scenarios like file Programming errors or unforeseen


issues. cases.
Creating Custom Exceptions

Java allows developers to create their own exceptions by extending the Exception or
RuntimeException class.

Steps to Create a Custom Exception:

1. Extend the Exception or RuntimeException class.


2. Define constructors to accept custom messages.

Example:

class CustomException extends Exception {


public CustomException(String message) {
super(message);
}
}

public class CustomExceptionExample {


public static void main(String[] args) {
try {
validateAge(15);
} catch (CustomException e) {
System.out.println("Caught Exception: " + e.getMessage());
}
}

static void validateAge(int age) throws CustomException {


if (age < 18) {
throw new CustomException("Age must be 18 or above!");
}
}
}

2. Multithreading in Java

Introduction

● Multithreading allows multiple threads (independent paths of execution) to run


concurrently in a program.
● Threads are lightweight sub-processes sharing the same memory space.

Benefits of Multithreading
1. Improved performance through parallelism.
2. Efficient CPU utilization.
3. Simplifies the program structure for handling multiple tasks.

Thread Life Cycle

1. New: Thread is created but not started (e.g., Thread t = new Thread();).
2. Runnable: Thread is ready to run but waiting for CPU (after calling start()).
3. Running: The thread is executing its run() method.
4. Waiting/Blocked: Thread is paused due to resource unavailability or conditions.
5. Terminated: Thread has completed execution or stopped.

Example of Thread Life Cycle:

class MyThread extends Thread {


public void run() {
System.out.println("Thread is running...");
}
}

public class ThreadLifeCycle {


public static void main(String[] args) {
MyThread t = new MyThread(); // New state
t.start(); // Runnable state
}
}

Thread Priorities and Scheduling

1. Priorities:
○ Threads have priorities ranging from 1 (MIN_PRIORITY) to 10
(MAX_PRIORITY).
○ Default priority is 5 (NORM_PRIORITY).
○ Higher-priority threads are executed before lower-priority threads, but this
depends on the OS and JVM.

Example of Setting Priorities:

class PriorityExample extends Thread {


public void run() {
System.out.println(Thread.currentThread().getName() + " with priority " +
Thread.currentThread().getPriority());
}
}

public class ThreadPriorityExample {


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

t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);

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

2. Scheduling:
○ The JVM thread scheduler determines which thread runs based on priorities.
○ Two main approaches:
■ Preemptive Scheduling: Higher-priority threads preempt lower-priority
threads.
■ Time-Slicing: Threads share CPU time in a round-robin manner.

Thread Synchronization

Synchronization ensures that multiple threads can access shared resources without conflicts.

Why Needed?

● To prevent race conditions, where multiple threads modify shared data simultaneously,
leading to inconsistent results.

How to Achieve Synchronization:

1. Synchronized Methods:

○ Only one thread can execute a synchronized method of an object at a time.

public synchronized void method() {


// Critical section
}
2.
3. Synchronized Blocks:

○ Locks only a portion of the code.

synchronized (object) {
// Critical section
}

4.

Example:

class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public int getCount() {


return count;
}
}

public class SynchronizationExample {


public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();

Thread t1 = new Thread(() -> {


for (int i = 0; i < 1000; i++) counter.increment();
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) counter.increment();
});

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

t1.join();
t2.join();

System.out.println("Final Count: " + counter.getCount());


}
}

Inter-Thread Communication

Inter-thread communication allows threads to communicate and coordinate tasks using methods
like wait(), notify(), and notifyAll().

Key Points:

● wait(): A thread releases the lock and enters the waiting state.
● notify(): Wakes up one thread waiting on the same object.
● notifyAll(): Wakes up all threads waiting on the same object.

Example: Producer-Consumer Problem

class SharedResource {
private int value = 0;
private boolean available = false;

public synchronized void produce(int newValue) {


while (available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
value = newValue;
available = true;
System.out.println("Produced: " + value);
notify();
}

public synchronized void consume() {


while (!available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed: " + value);
available = false;
notify();
}
}

public class InterThreadCommunication {


public static void main(String[] args) {
SharedResource resource = new SharedResource();

Thread producer = new Thread(() -> {


for (int i = 1; i <= 5; i++) {
resource.produce(i);
}
});

Thread consumer = new Thread(() -> {


for (int i = 1; i <= 5; i++) {
resource.consume();
}
});

producer.start();
consumer.start();
}
}

Summary

Exceptions:

● Provide a mechanism to handle runtime errors.


● Checked exceptions are compile-time enforced, while unchecked are runtime errors.
● Custom exceptions allow domain-specific error handling.

Multithreading:

● Threads improve application performance by enabling concurrent execution.


● Scheduling is priority-based, influenced by OS and JVM.
● Synchronization and inter-thread communication ensure safe access to shared
resources.

Let me know if you need further clarification or more examples! 😊


Detailed Explanation: Multithreading in Java

1. Introduction to Multithreading

Definition:
Multithreading in Java is the concurrent execution of multiple threads (independent units of a
program). Threads share the same memory space but execute independently.

Why Use Multithreading?

1. Improved Performance: Tasks can execute simultaneously, utilizing CPU resources


more effectively.
2. Concurrent Programming: Enables parallel execution, e.g., handling multiple user
requests in a server application.
3. Simplified Design: Tasks like animation or background computation can be separated
into threads.

Creating Threads in Java

1. Extending Thread Class

● Create a class that extends the Thread class and overrides the run() method.
● Start the thread using the start() method.

Example:

class MyThread extends Thread {


public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}

public class ThreadExample {


public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start(); // Starts the thread
}
}
2. Implementing Runnable Interface

● Create a class that implements the Runnable interface and defines the run() method.
● Pass the instance of this class to a Thread object and call start().

Example:

class MyRunnable implements Runnable {


public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}

public class RunnableExample {


public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
t1.start();
}
}

2. Thread Priorities and Scheduling

Thread Priorities

1. Priority Levels:

○ Range: 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY).


○ Default priority: 5 (NORM_PRIORITY).
○ Threads with higher priority are likely to be executed before lower-priority
threads, though this depends on the JVM and OS.
2. Setting Priority:

○ Use setPriority(int priority) to assign a priority to a thread.


○ Retrieve a thread’s priority using getPriority().

Example:

class PriorityThread extends Thread {


public void run() {
System.out.println(Thread.currentThread().getName() + " Priority: " +
Thread.currentThread().getPriority());
}
}

public class PriorityExample {


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

t1.setPriority(Thread.MIN_PRIORITY); // Priority 1
t2.setPriority(Thread.MAX_PRIORITY); // Priority 10

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

Thread Scheduling

1. Preemptive Scheduling:
○ Higher-priority threads interrupt lower-priority threads.
2. Time-Slicing:
○ Threads of the same priority share CPU time in a round-robin fashion.

3. Thread Life Cycle

A thread in Java goes through several states:

1. New:

○ Thread is created but not started.


○ Example: Thread t = new Thread();
2. Runnable:

○Thread is ready to execute after calling start(), but it may not be running if
CPU is busy.
○ Example: t.start();
3. Running:

○ Thread is executing its run() method.


4. Waiting/Blocked:
○Thread is waiting for a resource or signal, or is paused deliberately (e.g., using
wait() or sleep()).
5. Terminated:

○ Thread completes its task or is explicitly stopped.

Example of Thread Life Cycle:

class ThreadLifeCycle extends Thread {


public void run() {
System.out.println("Thread is running.");
}
}

public class LifeCycleExample {


public static void main(String[] args) {
ThreadLifeCycle t = new ThreadLifeCycle();
System.out.println("State: " + t.getState()); // New
t.start();
System.out.println("State after start(): " + t.getState()); // Runnable
}
}

4. Thread Synchronization

Definition:
Thread synchronization ensures that multiple threads access shared resources without
conflicts, avoiding race conditions.

Types of Synchronization

1. Synchronized Methods:
○ Ensures that only one thread can execute a method of an object at a time.
○ Declared using the synchronized keyword.

Example:

class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public int getCount() {


return count;
}
}

public class SynchronizedMethodExample {


public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();

Thread t1 = new Thread(() -> {


for (int i = 0; i < 1000; i++) counter.increment();
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) counter.increment();
});

t1.start();
t2.start();
t1.join();
t2.join();

System.out.println("Final Count: " + counter.getCount());


}
}

2. Synchronized Blocks:
○ Synchronizes a specific block of code rather than the entire method.

Example:

class SharedResource {
void display(String message) {
synchronized (this) {
System.out.println("[");
System.out.println(message);
System.out.println("]");
}
}
}
public class SynchronizedBlockExample {
public static void main(String[] args) {
SharedResource resource = new SharedResource();

Thread t1 = new Thread(() -> resource.display("Hello from Thread 1"));


Thread t2 = new Thread(() -> resource.display("Hello from Thread 2"));

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

3. Static Synchronization:
○ Used for synchronizing static methods.
○ Locks the class object rather than an instance.

Example:

class SharedResource {
public static synchronized void staticDisplay(String message) {
System.out.println("[");
System.out.println(message);
System.out.println("]");
}
}

5. Inter-Thread Communication

Java provides methods like wait(), notify(), and notifyAll() for communication
between threads.

Methods:

1. wait(): Causes the current thread to wait until another thread calls notify() or
notifyAll() on the same object.
2. notify(): Wakes up one thread waiting on the object's monitor.
3. notifyAll(): Wakes up all threads waiting on the object's monitor.

Example: Producer-Consumer Problem:


class SharedQueue {
private int value;
private boolean hasValue = false;

public synchronized void produce(int value) throws InterruptedException {


while (hasValue) {
wait(); // Wait for consumer to consume
}
this.value = value;
hasValue = true;
System.out.println("Produced: " + value);
notify();
}

public synchronized void consume() throws InterruptedException {


while (!hasValue) {
wait(); // Wait for producer to produce
}
System.out.println("Consumed: " + value);
hasValue = false;
notify();
}
}

public class ProducerConsumer {


public static void main(String[] args) {
SharedQueue queue = new SharedQueue();

Thread producer = new Thread(() -> {


try {
for (int i = 1; i <= 5; i++) queue.produce(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
});

Thread consumer = new Thread(() -> {


try {
for (int i = 1; i <= 5; i++) queue.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producer.start();
consumer.start();
}
}

Summary

Multithreading Concepts:

1. Introduction: Concurrent execution of threads.


2. Priorities and Scheduling: Threads with higher priorities execute first; uses preemptive
scheduling and time-slicing.
3. Thread Synchronization: Ensures thread-safe operations on shared resources using
synchronized methods and blocks.
4. Thread Life Cycle: New → Runnable → Running → Waiting/Blocked → Terminated.
5. Inter-Thread Communication: Enables threads to coordinate actions using wait(),
notify(), and notifyAll().

Let me know if you'd like additional examples or deeper explanations! 😊

You might also like