Module 5 Topic Wize Oops With Java 24-25
Module 5 Topic Wize Oops With Java 24-25
PREPARED BY
ARPITHA K M
Multithreading in Java
• Multithreading in Java is a powerful programming feature that allows
the execution of multiple threads simultaneously.
• A thread is the smallest unit of a process, and multithreading enables
the concurrent execution of two or more parts of a program to
maximize CPU utilization.
Key Concepts in Multithreading
• Thread: A thread is a lightweight subprocess, a smallest unit of
processing. Each thread in Java runs within a process.
• Main Thread: Every Java program has at least one thread, known as the
main thread. It is created automatically when the program starts.
• Concurrency: It allows multiple threads to run in overlapping time
periods, improving program efficiency.
• Parallelism: True parallel execution of threads on multi-core processors.
The Life Cycle/Model of a Thread in Java
The Life Cycle of a Thread in Java refers to the state
transformations of a thread that begins with its birth and
ends with its death.
When a thread instance is generated and executed by calling
the start() method of the Thread class, the thread enters the
runnable state.
When the sleep() or wait() methods of the Thread class are
called, the thread en
ters a non-runnable mode.
Thread returns from non-runnable state to runnable state and
starts statement execution.
The thread dies when it exits the run() process.
There are basically 4 stages in the lifecycle of a thread, as given below:
New
Runnable
Running
Blocked (Non-runnable state)
Dead
1) New State
• As we use the Thread class to construct a thread entity, the thread
is born and is defined as being in the New state.
• That is, when a thread is created, it enters a new state, but the
start() method on the instance has not yet been invoked.
Ex: Thread t = new Thread();
2) Runnable State
• A thread in the runnable state is prepared to execute the code.
When a new thread's start() function is called, it enters a runnable
state.
• In the runnable environment, the thread is ready for execution and
is awaiting the processor's availability (CPU time).
• That is, the thread has entered the queue (line) of threads waiting
for execution.
EX: t.start();
3) Running State
Running implies that the processor (CPU) has assigned a time slot to the thread for execution.
When a thread from the runnable state is chosen for execution by the thread scheduler, it
joins the running state.
In the running state, the processor allots time to the thread for execution and runs its run
procedure.
This is the state in which the thread directly executes its operations. Only from the runnable
state will a thread enter the running state.
The thread is executing its run() method.
4) Blocked State
When the thread is alive, i.e., the thread class object persists, but it cannot be selected for
execution by the scheduler. It is now inactive.
Ex: Thread.sleep();
5)Dead State
When a thread's run() function ends the execution of sentences, it automatically dies or
enters the dead state.
That is, when a thread exits the run() process, it is terminated or killed. When the stop()
function is invoked, a thread will also go dead.
Ex: t.join();
1. Extending the Thread Class
When you extend the Thread class, you create a subclass of Thread and override its run() method.
The run() method contains the code that will execute when the thread starts.
class MyThread extends Thread {
public void run() {
// Code executed by the thread
for (int i = 1; i <= 5; i++) {
System.out.println("Thread running: " + i);
try {
Thread.sleep(500); // Pausing for 500 milliseconds
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread(); // Create an instance of the thread
thread.start(); // Start the thread
}
}
2. Implementing the Runnable Interface
• When you implement the Runnable interface, you create a class that implements Runnable and provide the
thread logic inside the run() method.
• Then, you pass an instance of this class to a Thread object.
Locks at the class level, ensuring no thread can execute any static
synchronized method of the class until the lock is released.
class Counter {
private static int count = 0;
OUTPUT:Producing...
Consuming...
SUSPENDING,RESUMING,AND STOPPING
THREADS
1.Java Thread suspend() method and resume() method
The suspend() method of thread class puts the thread from
running to waiting state.
This method is used if you want to stop the thread execution and
start it again when a certain event occurs.
method allows a thread to temporarily cease execution. The
suspended thread can be resumed using the resume() method.
Use a shared flag (volatile boolean) and synchronization to
achieve thread suspension and resumption safely.
Syntax
public final void suspend()
class SuspendResumeExample implements Runnable {
private volatile boolean suspended = false;
public synchronized void suspendThread() {
suspended = true;
}
public synchronized void resumeThread() {
suspended = false;
notify(); // Notify the thread to resume
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (this) {
while (suspended) {
try {
wait(); // Wait until notified to resume
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Thread interrupted.");
}
}
}
System.out.println("Running: " + i);
try {
Thread.sleep(500); // Simulate work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Thread interrupted during sleep.");
}
}
}
}
public class ThreadControlDemo {
public static void main(String[] args) throws InterruptedException {
SuspendResumeExample example = new SuspendResumeExample();
Thread thread = new Thread(example);
thread.start();
Thread.sleep(2000); // Let the thread run for a while
System.out.println("Suspending thread...");
example.suspendThread();
Thread.sleep(2000); // Wait while the thread is suspended
System.out.println("Resuming thread...");
example.resumeThread();
}
}
OUTPUT
Running: 1
Running: 2
Suspending thread...
Resuming thread...
Running: 3
Running: 4
...
2. Stopping a Thread
Stopping a thread terminates its execution completely.
The stop() method is deprecated because it can leave shared resources in an inconsistent state.
Instead, use a shared flag to signal the thread to stop gracefully.
Output
Thread is running...
Thread is running...
Thread is running...
Stopping thread...
Thread stopped.
Obtain a thread's state
In Java, you can obtain a thread's state using the Thread class's getState() method.
This method returns a value from the Thread.State enum, which represents the
different states a thread can be in during its lifecycle.
Thread States
Java defines the following states for a thread:
1) NEW: A thread is in the NEW state after it has been created but before the start()
method has been invoked.
2) RUNNABLE: A thread enters the RUNNABLE state after the start() method has
been called. In this state, the thread is eligible for execution by the Java Virtual
Machine (JVM), but it may not be running at all times because other threads could
be executing. This is the state where a thread is actively running or waiting for a
CPU time slice.
3) BLOCKED: A thread enters the BLOCKED state when it is waiting for a monitor lock
to enter a synchronized block or method. When another thread is holding the
lock, the thread is blocked.
4) WAITING: A thread is in the WAITING state when it is waiting
indefinitely for another thread to perform a particular action. This is
typically the result of calling methods like Thread.sleep(),
Object.wait(), or LockSupport.park().
Output
MONDAY is a Weekday
TUESDAY is a Weekday
WEDNESDAY is a Weekday
THURSDAY is a Weekday
FRIDAY is a Weekday
SATURDAY is a Weekend
SUNDAY is a Weekend
Today is: MONDAY
Ordinal of SUNDAY: 6
5.Instantiation:Enumerations define a class type, but they are not
instantiated using the newkeyword.
Enumeration variables are declared and used similarly to primitive types.
6.Assignment and Comparison:
Enumeration variables can only hold values defined by the
enumeration.
Constants can be assigned to enumeration variables using the dot
notation( EnumType.Constant)
Constants can be compared for equality using the == operator
7.Switch Statements:Enumeration values can be used to control
switch statements.
All case statements within the switch must use constants from the
same enum as the switch expression.
Constants in case statements are referenced without qualification
by their enumeration type name.
values() and valueOf() methods
In Java, both the values() and valueOf() methods are built-in
methods available to all enum types.
These methods are automatically provided by the Java compiler
when you define an enum type.
1. values() Method
• The values() method is implicitly provided by Java for all enums.
This method returns an array of all the constants of the enum
type in the order they are declared.
OUTPUT: MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
2. valueOf(String name) Method
The valueOf() method is another built-in
method that is used to convert a String to its
corresponding enum constant.
OUTPUT:
Day is: MONDAY
Invalid day: No enum constant Day.FUNDAY
Type Wrappers
• The wrapper class in Java provides the mechanism to
convert primitive into object and object into primitive.
• Type Wrappers in Java are utility classes provided in the
java.lang package.
• They are used to wrap primitive data types into objects,
allowing them to be treated as objects when required.
• These classes are essential for Java's object-oriented
nature, as they allow primitives to work seamlessly with
APIs that require objects, such as Java Collections.
Primitive Type Wrapper Class
byte Byte
char Character
short Short
int Int
long Long
float Foat
double Double
boolean Boolean
1. Character Wrapper Class
• The Character wrapper class wraps a char primitive into an object. It also
provides utility methods for character manipulation and testing.
public class CharacterWrapperExample {
public static void main(String[] args) {
// Creating a Character object
Character ch = 'A';
// Using Character utility methods
System.out.println("Is 'A' a letter? " + Character.isLetter(ch)); // true
System.out.println("Is 'A' a digit? " + Character.isDigit(ch)); // false
System.out.println("Lowercase of 'A': " + Character.toLowerCase(ch)); //
'a'
System.out.println("Is 'A' uppercase? " + Character.isUpperCase(ch)); //
true
}
}
2. Boolean Wrapper Class
The Boolean wrapper class wraps a boolean primitive into an object.It provides
methods for logical operations and conversions.
public class BooleanWrapperExample {
public static void main(String[] args) {
// Creating Boolean objects
Boolean isTrue = Boolean.TRUE; // Using constants
Boolean isFalse = Boolean.FALSE;
// Logical operations
System.out.println("Logical AND: " + (isTrue & isFalse)); // false
System.out.println("Logical OR: " + (isTrue | isFalse)); // true
// Parsing and valueOf
Boolean parsedValue = Boolean.parseBoolean("true");
System.out.println("Parsed boolean: " + parsedValue); // true
// String conversion
System.out.println("String representation: " + isTrue.toString()); // "true"
}
}
3. Numeric Type Wrappers
• These wrappers (Byte, Short, Integer, Long, Float, Double) wrap numeric primitives into objects. They also provide utility
methods for parsing, comparisons, and mathematical operations.
public class NumericWrapperExample {
public static void main(String[] args) {
// Integer wrapper
Integer intValue = 42;
System.out.println("Integer value: " + intValue);
// Converting Integer to String
String intString = intValue.toString();
System.out.println("String representation of Integer: " + intString);
// Parsing String to Integer
int parsedInt = Integer.parseInt("123");
System.out.println("Parsed Integer: " + parsedInt);
// Double wrapper
Double doubleValue = 3.14;
System.out.println("Double value: " + doubleValue);
// Math operations
Double sum = Double.sum(5.5, 2.5);
System.out.println("Sum of 5.5 and 2.5: " + sum);
// Comparing two numeric objects
Integer num1 = 100;
Integer num2 = 200;
System.out.println("Comparison result: " + Integer.compare(num1, num2)); // -1
}
}
Autoboxing and Unboxing in Java
• Autoboxing: Automatic conversion of primitive
types into their corresponding wrapper class
objects (e.g., int to Integer).
• Unboxing: Automatic conversion of wrapper
class objects back into their corresponding
primitive types (e.g., Integer to int).
1. Autoboxing in Methods
Java allows primitive values to be automatically boxed when passed
to methods expecting wrapper class arguments.
value:10
• 2. Autoboxing/Unboxing in Expressions
Autoboxing and unboxing occur automatically in expressions where primitives and wrapper
objects interact.
Sum: 50
Result as Integer: 50
• 3. Autoboxing/Unboxing Boolean Values
Boolean values are also autoboxed and unboxed in logical expressions and method calls.