0% found this document useful (0 votes)
30 views24 pages

Theory Concepts After Oops

Uploaded by

s14anj
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)
30 views24 pages

Theory Concepts After Oops

Uploaded by

s14anj
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/ 24

THEORY

CONCEPTS
AFTER
OOPS
EXCEPTION HANDLING
only one exception will be handled the 1st on will be handled after that it wont
be handled,even if there is a exception type of its ,its handled by its own
method only if its type is not present then only exception type will be handled
and can't write any catch blocks after exception type it wont be reached
public class Prg3 {
public static void main(String[] args) {
try {

String s = "abc";
char c = s.charAt(5);

int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Caught an ArithmeticException.");
}
catch (StringIndexOutOfBoundsException e) {
System.out.println("Caught a StringIndexOutOfBoundsException.");
}
catch(Exception e) {
System.out.println("same type handled");
}
}
}
NESTED BLOCK:
package ExceptionHnadling;

public class Prg4 {


public static void main(String[] args) {
try {
System.out.println("Outer try block.");
// This will throw a StringIndexOutOfBoundsException
String s = "Hello";
char c = s.charAt(10); // Attempting to access an invalid index

try {
// This line won't execute because the outer try will throw an
exception
int result = 10 / 0; // This would throw an ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Inner catch block: ArithmeticException
caught.");
}
} catch (StringIndexOutOfBoundsException e) {
System.out.println("Outer catch block:
StringIndexOutOfBoundsException caught.");
} catch (Exception e) {
System.out.println("Outer catch block: Some other exception
caught.");
}
}
}
SYNTAX:
try{
try{
catch(){
}}catch(){
Try{
}
Catch(){
}}

FINALLY BLOCK:
package ExceptionHnadling;
// finally is will get executed even if u handle the execution or not
public class Prg5 {
public static void main(String[] args) {

int[] numbers = {1, 2, 3};


int divisor = 0;

try {
System.out.println("Accessing element at index 5:");
int num = numbers[5]; // This will throw
IndexOutOfBoundsException

System.out.println("Dividing 10 by divisor:");
int result = 10 / divisor; // This would throw ArithmeticException
if it were reached
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Caught ArithmeticException: " +
e.getMessage());
} catch (IndexOutOfBoundsException e) {
System.out.println("Caught IndexOutOfBoundsException: " +
e.getMessage());
} finally {
System.out.println("Finally block executed.");
}

System.out.println("Program continues after try-catch-finally.");


}
}

EXCPTION PROPAGATION:
Passing a exception to its caller method is called exception propagation
TYPES:
 CHECKED
 UNCHECKED

CHECKED
import java.io.FileReader;
import java.io.IOException;

public class ThrowsExample {

// Method that declares it may throw IOException


public void readFile() throws IOException {
FileReader file = new FileReader("file.txt");
file.read();
file.close();
}

public static void main(String[] args) {


ThrowsExample example = new ThrowsExample();
try {
example.readFile();
} catch (IOException e) {
System.out.println("An error occurred: " + e.getMessage());
}
}
}

UNCHECKED:
Check the examples
PROPAGATION EXAMPLE:
package ExceptionHnadling;

public class Prg6


public static void main(String[] args) {
try {
level1();
} catch (ArithmeticException e) {
System.out.println("Caught in main: " + e.getMessage());
}
}

static void level1() {


level2();
}

static void level2() {


level3();
}

static void level3() {


// This will throw an ArithmeticException
int result = 10 / 0;
}
}
THROWS AND THROW
public class ThrowExample {
public static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or older to register.");
}
System.out.println("You are eligible to register.");
}

public static void main(String[] args) {


try {
checkAge(16); // Will throw an IllegalArgumentException
} catch (IllegalArgumentException e) {
System.out.println("Caught an exception: " + e.getMessage());
}
}
}

Aspect throw throws

Used in a method
Used to explicitly throw an exception in signature to declare
Purpose
code. exceptions that might be
thrown by the method.

Appears in the method


Position in
Appears within a method body. signature, after the
Code
parameter list.

Primarily used to declare


Type of Can throw both checked and unchecked checked exceptions
Exceptions exceptions. (although unchecked can
be declared as well).

Informs the caller of


Directly causes an exception, triggering
potential exceptions,
Exception immediate control transfer to the nearest
requiring them to handle or
Handling matching catch block or propagating up
further declare these
the stack.
exceptions.

Used to specify what


exceptions a method might
Used when an actual exception instance throw, allowing the caller
Usage needs to be thrown (e.g., throw new to handle those exceptions
IllegalArgumentException("Invalid input");). (e.g., public void
myMethod() throws
IOException).

MULTITASING
TYPES:
In process-based multitasking, multiple independent programs (processes) are run
concurrently. Each process has its own memory space, program code, and data. The
operating system allocates resources to each process and ensures they don’t
interfere with each other.
 Example: Running a browser, a text editor, and a media player
simultaneously on a computer.
Thread-based multitasking, also known as multithreading, involves dividing a
single process into multiple threads. Each thread can perform a different task within
the same program, sharing the same memory and resources.
 Example: A web browser with multiple tabs, where each tab runs as a
separate thread within the same process.
THREAD:
a thread is the smallest unit of execution within a process. It represents a single
sequence of instructions that can be managed independently by the operating
system's scheduler. Threads allow a program to perform multiple tasks
simultaneously, which is particularly useful in applications requiring responsiveness,
concurrency, or parallelism.
EXAMPLE 1
class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread " + Thread.currentThread().getId() + " is running,
iteration: " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
}

public class ThreadExample {


public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start();
thread2.start();
}
}

EXAMPLE 2:
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running: " + Thread.currentThread().getName());
}
}

public class ThreadExample {


public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.start(); // Starts the first thread

MyThread thread2 = new MyThread();


thread2.start(); // Starts the second thread
}
}

EXAMPLE 3:
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread " + Thread.currentThread().getId() + " is running,
iteration: " + i);
try {
Thread.sleep(500); // Pause for 500 milliseconds
} catch (InterruptedException e) {
System.out.println("Thread interrupted: " + e.getMessage());
}
}
}
}

public class RunnableExample {


public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();

Thread thread1 = new Thread(myRunnable); // Create thread with MyRunnable


task
Thread thread2 = new Thread(myRunnable);

thread1.start(); // Start the threads


thread2.start();
}
}

RUN() AND START():

Aspect start() Method run() Method

Begins a new thread of Contains the code that defines the task or
Purpose
execution in the JVM. job the thread will execute.

How it Invokes the run() method in a Executes in the current thread without
Works new, separate thread. creating a new thread.
Used Starting a thread in a separate, Defining the behavior of the thread
For concurrent execution path. (the code it runs).

Creates a new thread and then Runs as a normal method within the
Behavior
invokes run() on that thread. current thread if called directly.

start() is always run() is usually called indirectly through


Typical
used to initiate a start() but can be called directly (not
Usage
new thread. recommended).

Thread life cycle


New → start() → Runnable
Runnable → Running (when the CPU picks it)
Running → Blocked/Waiting/Timed Waiting (if it encounters blocking
conditions, waits for another thread, or is told to wait)
Blocked/Waiting/Timed Waiting → Runnable (when conditions are met or time
expires)
Running → Terminated (when it completes execution or encounters a fatal error)

Reading and modifying the thread name


public class ThreadNameExample {

public static void main(String[] args) {

// Creating a new thread with a custom name


Thread myThread = new Thread(() -> {
System.out.println("Current thread name: " +
Thread.currentThread().getName());

// Modifying the thread name


Thread.currentThread().setName("ModifiedThreadName");
System.out.println("Thread name after modification: " +
Thread.currentThread().getName());
}, "InitialThreadName");

// Start the thread


myThread.start();

// Main thread continues running


System.out.println("Main thread name: " + Thread.currentThread().getName());
}
}

THREAD PRIORITY
public class ThreadPriorityExample {

public static void main(String[] args) {


// Create three threads with different priorities
Thread highPriorityThread = new Thread(new Task(), "HighPriorityThread");
Thread normalPriorityThread = new Thread(new Task(),
"NormalPriorityThread");
Thread lowPriorityThread = new Thread(new Task(), "LowPriorityThread");

// Set different priorities


highPriorityThread.setPriority(Thread.MAX_PRIORITY); // Priority 10
normalPriorityThread.setPriority(Thread.NORM_PRIORITY); // Priority 5
lowPriorityThread.setPriority(Thread.MIN_PRIORITY); // Priority 1
// Start all threads
lowPriorityThread.start();
normalPriorityThread.start();
highPriorityThread.start();
}

// A simple task for the threads to execute


static class Task implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " - Priority: "
+ Thread.currentThread().getPriority() + " - Count: " + i);
}
}
}
}

Thread.MIN_PRIORITY = 1 (lowest priority)


Thread.NORM_PRIORITY = 5 (default priority)
Thread.MAX_PRIORITY = 10 (highest priority)
Using sleep()
 Description: Thread.sleep(milliseconds) pauses the current thread for a
specified duration (in milliseconds). During this time, the thread is moved to a
TIMED_WAITING state.
 Example:
java
Copy code
Thread.sleep(1000); // Pauses execution for 1 second
 Use Case: To introduce delays or to allow other threads to execute.
2. Using wait()
 Description: wait() causes the current thread to release its lock on an object
and enter the WAITING state until it is notified (using notify() or notifyAll()) by
another thread.
 Example:
java
Copy code
synchronized(object) {
object.wait(); // Pauses execution until another thread calls object.notify()
}
 Use Case: Typically used in inter-thread communication (e.g., producer-
consumer problems).
3. Using join()
 Description: When a thread calls join() on another thread, it waits for that
thread to complete. The calling thread is moved to the WAITING state until
the other thread finishes execution.
 Example:
java
Copy code
Thread t = new Thread(new Task());
t.start();
t.join(); // The current thread will wait until thread t finishes
 Use Case: To ensure that a particular thread completes before proceeding
(e.g., waiting for data loading threads before processing).
4. Using Locks (e.g., synchronized blocks)
 Description: When a thread tries to enter a synchronized block or method
that is currently held by another thread, it is blocked until the lock becomes
available.
 Example:
java
Copy code
synchronized(lockObject) {
// Code that only one thread can execute at a time
}
 Use Case: Useful for preventing race conditions when accessing shared
resources.
5. Using yield()
 Description: Thread.yield() gives a hint to the thread scheduler that the
current thread is willing to yield its execution. This means it gives other
threads an opportunity to execute.
 Example:
java
Copy code
Thread.yield(); // Suggests to the scheduler to pause this thread and allow others to
execute
 Use Case: Often used in fine-tuning performance but generally unpredictable,
as it depends on the thread scheduler.
6. Using interrupt()
 Description: interrupt() is used to signal to a thread that it should stop its
current task and respond to the interruption. If a thread is sleeping or waiting,
calling interrupt() will throw an InterruptedException.
 Example:
java
Copy code
Thread t = new Thread(new Task());
t.start();
t.interrupt(); // Sends an interrupt signal to thread t
 Use Case: Useful for gracefully stopping a thread, especially when you need
to stop it from outside.
7. Setting Thread Flags (Custom Implementation)
 Description: You can implement a boolean flag within a thread class to check
if it should keep running. When the flag is true, the thread continues; when
false, it stops.
 Example:
java
Copy code
class MyThread extends Thread {
private volatile boolean keepRunning = true;

public void run() {


while (keepRunning) {
// Thread logic here
}
}

public void stopRunning() {


keepRunning = false;
}
}
 Use Case: This is a common method for gracefully stopping a thread without
forcefully interrupting it.
8. Using stop() (Deprecated)
 Description: The stop() method was originally intended to forcefully stop a
thread. However, it’s deprecated due to unsafe handling of locks and resource
states.
 Example:
java
Copy code
thread.stop(); // Not recommended
 Use Case: Not recommended. It is replaced by more controlled approaches
like interruption and flags.
Summary of Methods to Prevent Execution

Method State Entered Use Case

sleep() TIMED_WAITING Pausing execution for a fixed time

Pausing until notified by another


wait() WAITING
thread

Waiting for another thread to


join() WAITING
finish
Method State Entered Use Case

Waiting for a lock held by another


Locks BLOCKED
thread

Giving other threads a chance to


yield() Depends on scheduler
run

INTERRUPTED/handling Safely stopping a thread’s


interrupt()
exception execution

Graceful thread stopping or


Flag Check Custom state
pausing

stop() Forcefully stops a thread (not


Terminated (unsafe)
(deprecated) recommended)

DAEMON AND NON DAEMON THEADS:


public class DaemonExample {

public static void main(String[] args) {


// Creating a user (non-daemon) thread
Thread userThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("User thread is running...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("User thread completed.");
});

// Creating a daemon thread


Thread daemonThread = new Thread(() -> {
while (true) { // Infinite loop to simulate a background task
System.out.println("Daemon thread is running in the background...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
daemonThread.setDaemon(true); // Set this thread as daemon

// Start both threads


userThread.start();
daemonThread.start();

// Main thread ends here


System.out.println("Main thread is ending.");
}
}
Main thread is ending.
Daemon thread is running in the background...
User thread is running...
Daemon thread is running in the background...
User thread is running...
...
User thread completed.

Feature Daemon Thread Non-Daemon (User) Thread

Purpose Background, support tasks Core application tasks


JVM Shutdown JVM exits when only daemon JVM waits for all user threads
Behavior threads remain to complete

Default Must be set explicitly with Created as non-daemon by


Behavior setDaemon(true) default

Typical Use Logging, monitoring, garbage Processing user input, data


Cases collection operations

Priority and Often lower priority than user Can have any
Scheduling threads priority

SYNCHORIZATION:
In Java, synchronization is achieved by using the synchronized keyword on methods
or blocks of code. When a method or block is marked as synchronized, it acquires a
lock to prevent other threads from accessing the same method or block until the lock
is released.
class Counter {
private int count = 0;

// Synchronized method to increment count


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 to increment the counter


Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

// Another thread to increment the counter


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());


}
}
CLASS LEVEL AND OBJECT LEVEL LOCK:
Object-Level Lock
Object-level lock is acquired on an instance of a class. This type of lock is applied
when we want to ensure that only one thread can access an instance method at a
time.
Example of Object-Level Lock
java
Copy code
class Printer {
public void printDocument(String document) {
synchronized (this) { // Object-level lock
for (int i = 1; i <= 5; i++) {
System.out.println(document + " - Page " + i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

public class ObjectLevelLockExample {


public static void main(String[] args) {
Printer printer = new Printer();

// Two threads trying to access printDocument method


Thread t1 = new Thread(() -> printer.printDocument("Thread-1 Document"));
Thread t2 = new Thread(() -> printer.printDocument("Thread-2 Document"));

t1.start();
t2.start();
}
}
Explanation
 Here, synchronized(this) locks on the Printer instance (printer), so only one
thread can access printDocument() at a time for that specific instance.
 If multiple instances of Printer existed, each instance would have its own lock,
and different threads could access printDocument() on different instances
concurrently.
3. Class-Level Lock
Class-level lock is acquired on the class object itself, which is the .class object
associated with a class. This type of lock is used when we want to synchronize static
methods or blocks across all instances of a class, ensuring that only one thread can
access the synchronized block or method at a time for the entire class.
Example of Class-Level Lock
java
Copy code
class Database {
// Static synchronized method (class-level lock)
public static synchronized void accessDatabase(String threadName) {
for (int i = 1; i <= 5; i++) {
System.out.println(threadName + " is accessing the database - Step " + i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

public class ClassLevelLockExample {


public static void main(String[] args) {
// Two threads accessing a static synchronized method
Thread t1 = new Thread(() -> Database.accessDatabase("Thread-1"));
Thread t2 = new Thread(() -> Database.accessDatabase("Thread-2"));

t1.start();
t2.start();
}
}
Explanation
 The accessDatabase() method is static synchronized, meaning it uses a
class-level lock.
 Since this lock is on the Database.class object, only one thread can execute
accessDatabase() at a time across all threads, regardless of the instance.
 Even if multiple Database instances are created, accessDatabase() can only
be accessed by one thread at a time because of the class-level lock.

You might also like