0% found this document useful (0 votes)
3 views40 pages

Enotes - Unit 3 - Java Programming

The document provides study material for a Java Programming course, focusing on packages, exception handling, and threading. It covers the concepts of package hierarchy, access control modifiers, and different types of exceptions, including user-defined exceptions. The document also explains the importance of packages in organizing code and preventing name conflicts, as well as the various access modifiers and their implications in Java programming.

Uploaded by

hema subi
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)
3 views40 pages

Enotes - Unit 3 - Java Programming

The document provides study material for a Java Programming course, focusing on packages, exception handling, and threading. It covers the concepts of package hierarchy, access control modifiers, and different types of exceptions, including user-defined exceptions. The document also explains the importance of packages in organizing code and preventing name conflicts, as well as the various access modifiers and their implications in Java programming.

Uploaded by

hema subi
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

MARUDHAR KESARI JAIN COLLEGE FOR WOMEN (AUTONOMOUS)

VANIYAMBADI
PG Department of Computer Applications

I M.C.A - Semester - II

E-Notes (Study Material)

Core Course-2 : Java Programming Code: 24PCAC22

Unit: 3 – Packages– Package Hierarchy, Import Statement, Hiding the Classes, Access
Control Modifiers, Exception Handling – Default Exception – User Defined Exception
Handling, Exception and Error Classes, Throw and Throws. Threading– Life Cycle,
Creating and Running, Methods in Thread Class, Priority Thread, Synchronization, Dead
Lock, Inter Thread Communication.

Learning Objectives: To understand the concept of package, Exception Handling and


Threading.
Course Outcomes: The student will be able to understand the concept of package,
Exception Handling and Threading

Overview

Packages

– Package Hierarchy, Import Statement, Hiding the Classes

– Access Control Modifiers

Exception Handling

– Default Exception – User Defined Exception Handling

– Exception and Error Classes, Throw and Throws.

Threading

– Life Cycle, Creating and Running, Methods in Thread Class

– Priority Thread, Synchronization, Dead Lock, Inter Thread Communication.


Package

A package in Java is used to group related classes. Think of it as a folder in a file directory. We use
packages to avoid name conflicts, and to write a better maintainable code.

Syntax : package package_name;

Packages are divided into two categories:

 Built-in Packages (packages from the Java API)


 User-defined Packages (create your own packages)

1. Built-in Packages
Built-in Packages comprise a large number of classes that are part of the Java API. Some of the
commonly used built-in packages are:
 [Link]: Contains language support classes(e.g, classes that define primitive data types, math
operations). This package is automatically imported.
 [Link]: Contains classes for supporting input/output operations.
 [Link]: Contains utility classes that implement data structures such as Linked Lists and
Dictionaries, as well as support for date and time operations.
 [Link]: Contains classes for creating Applets.
 [Link]: Contains classes for implementing the components for graphical user interfaces (like
buttons, menus, etc).

Example: Using [Link] (Built-in Package)

import [Link]; // built-in package

public class GFG{

public static void main(String[] args) {

// using Random class

Random rand = new Random();

// generates a number between 0–99

int number = [Link](100);

[Link]("Random number: " + number);

}
} // Output Random number: 59

2. User-defined Packages

User-defined Packages are the packages that are defined by the user.

Example:

package [Link];

public class Helper {

public static void show() {

[Link]("Hello from Helper!");

To use it in another class:

import [Link];

public class Test {

public static void main(String[] args) {

[Link]();

Accessing Classes Inside a Package

In Java, we can import classes from a package using either of the following methods:

1 Import a Single Class

import [Link];

This imports only the Vector class from the [Link] package.

2. Import all classes from a package:

import [Link].*;

This imports all classes and interfaces from the [Link] package but does not include sub-
packages.
Advantages of Packages

 Organizes large programs


 Avoids class name conflicts
 Provides access control (security)
 Makes code reusable and maintainable

Package Hierarchy

Packages can contain sub-packages, forming a hierarchical structure similar to directories. Packages can
be nested, forming a hierarchy similar to folders in a file system.

Example Hierarchy

java
└── util
└── ArrayList
Code Example

package [Link];

This means:

 com → top-level package


 company → sub-package
 project → sub-package
 module → sub-package

3. Import Statement

The import statement allows access to classes defined in other packages without using their fully
qualified names.

Types of Import

1. Single Class Import

import [Link];

2. Entire Package Import

import [Link].*;

3. Without Import (Fully Qualified Name)

[Link] sc = new [Link]([Link]);

Note: Importing a package does not import its sub-packages automatically.

Access Modifiers (Hiding the Classes)


Java uses access modifiers to hide or expose classes, methods, and variables.

Hiding Classes Using Packages

A class declared without public is accessible only within the same package

This helps in encapsulation and security

Example

class HiddenClass {

// accessible only within the same package

public class VisibleClass {

// accessible everywhere

Rule: A source file can have only one public class, and its name must match the file name.

Summary (Quick Revision)

 Package → Groups related classes


 Package Hierarchy → Nested package structure
 Import → Allows easy access to external classes
 Hiding Classes → Achieved using access modifiers
 Default access helps hide classes within a package

Access Control Modifiers

Java access modifiers are used to specify the scope of the variables, data members, methods, classes, or
constructors. These help to restrict and secure the access (or, level of access) of the data.
There are four different types of access modifiers in Java, we have listed them as follows:

 Default (No keyword required)


 Private
 Protected
 Public

Default Access Modifier

Default access modifier allows class members to be accessed only within the same package.

Default access modifier means we do not explicitly declare an access modifier for a class, field,
method, etc.

A variable or method declared without any access control modifier is available to any other class in the
same package. The fields in an interface are implicitly public static final and the methods in an
interface are by default public.

Example of Default Access Modifiers

Variables and methods can be declared without any modifiers, as in the following examples –

// File: [Link]
package pack1;

class A { // default access class


int x = 10; // default access variable

void show() { // default access method


[Link](x);
}
}

// File: [Link]
package pack1;

class B {
public static void main(String[] args) {
A obj = new A(); // allowed (same package)
[Link]();
}
}

This works because both classes are in the same package (pack1).
Access from Another Package (Not Allowed)

// File: [Link]
package pack2;

class C {
public static void main(String[] args) {
A obj = new A(); // ❌ERROR
}
}

Error occurs because class A has default access and is not visible outside its package.

Diagram
Package pack1 Package pack2
------------- -------------
class A --------X----> Not Accessible
class B

Key Exam Points ⭐

 No keyword → default access

 Accessible only within same package

 Helps in hiding classes and members

 Top-level classes can be default

Private Access Modifier

Methods, variables, and constructors that are declared private can only be accessed within the declared
class itself.

Private access modifier is the most restrictive access level. Class and interfaces cannot be private.

Variables that are declared private can be accessed outside the class, if public getter methods are present
in the class.

Using the private modifier is the main way that an object encapsulates itself and hides data from the
outside world.

Examples of Private Access Modifiers

Example 1

The following class uses private access control –


class A

private int x = 10; // private variable

private void show() { // private method

[Link](x);

void display()

{ // default method

show(); // allowed (same class)

Access from Another Class (Not Allowed)

class B {

public static void main(String[] args) {

A obj = new A();

// obj.x = 20; // ❌ERROR

// [Link](); // ❌ERROR

[Link](); // ✔ allowed

x and show() cannot be accessed outside class A.

Key Exam Points ⭐

 private is the most restrictive


 Accessible only within the same class
 Used to protect data
 Supports encapsulation
Public Access Modifier

A class, method, constructor, interface, etc. declared public can be accessed from any other class.
Therefore, fields, methods, blocks declared inside a public class can be accessed from any class
belonging to the Java Universe.
However, if the public class we are trying to access is in a different package, then the public class still
needs to be imported. Because of class inheritance, all public methods and variables of a class are
inherited by its subclasses.

Syntax

The following function uses public access control −

public static void main(String[] arguments) {


// ...
}
This example demonstrates the use of public access modifier.

// Class One
class One {
public void printOne() {
[Link]("printOne method of One class.");
}
}

public class Main {


public static void main(String[] args) {
// Creating an object of class One
One obj = new One();

// Calling printOne() method of class One


[Link]();
}
}
//Output : This example demonstrates the use of public access modifier.

Protected Access Modifier

Variables, methods, and constructors, which are declared protected in a superclass can be accessed only
by the subclasses in other package or any class within the package of the protected members' class.

The protected access modifier cannot be applied to class and interfaces. Methods, fields can be declared
protected, however methods and fields in a interface cannot be declared protected.

Protected access gives the subclass a chance to use the helper method or variable, while preventing a
nonrelated class from trying to use it.
Example:
package [Link].pack1;

class Animal
{
protected String name;
protected void makeSound() {
[Link]("Animal makes a sound");
}
}

class Dog extends Animal {


public void displayInfo() {
// Accessing protected attribute from parent class
name = "Buddy";
[Link]("Dog's name: " + name);
// Accessing protected method from parent class
makeSound();
}
}

public class ProtectedExample {


public static void main(String[] args) {
Dog myDog = new Dog();
[Link]();
}

Output:

Dog's name: Buddy


Animal makes a sound

Example 2: Access by a subclass in a different package

This scenario highlights a key feature of protected: accessibility across package boundaries via
inheritance

package [Link].pack1;

public class Vehicle {


protected String brand = "Ford";

protected void honk() {


[Link]("Tuut, tuut!");
}
}

package [Link].pack2;

import [Link]; // Import the parent class

class Car extends Vehicle {


private String model = "Mustang";

public static void main(String[] args) {


Car myCar = new Car();

// Accessing protected attribute from different package via inheritance


[Link]("Brand: " + [Link]);

// Accessing protected method from different package via inheritance


[Link]();

[Link]("Model: " + [Link]);


}
}

Output:

Brand: Ford
Tuut, tuut!
Model: Mustang

Key Points on protected Access

 Same Class: Yes, accessible.


 Same Package (different class): Yes, accessible.
 Different Package (subclass): Yes, accessible (as demonstrated in Example 2).
 Different Package (non-subclass): No, not accessible.
Exception Handling

Exception handling is a mechanism to handle runtime errors, allowing the normal flow of a
program to continue. Exceptions are events that occur during program execution that disrupt the
normal flow of instructions.

It uses different keywords:

 The try statement allows you to define a block of code to be tested for errors while it is
being executed.
 The catch statement allows you to define a block of code to be executed, if an error
occurs in the try block.
 The try and catch keywords come in pairs:
Syntax
try {
// Block of code to try
}
catch(Exception e) {
// Block of code to handle errors
}

Basic try-catch Example

 The try block contains code that might throw an exception,


 The catch block handles the exception if it occurs.

class Geeks{

public static void main(String[] args)

int n = 10;

int m = 0;

try

int ans = n / m;

[Link]("Answer: " + ans);

catch (ArithmeticException e)

[Link]("Error: Division by 0!");


}

} Output Error: Division by 0!

Consider the following example:

This will generate an error, because myNumbers[10] does not exist.

public class Main {

public static void main(String[ ] args) {

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

[Link](myNumbers[10]); // error!

The output will be something like this:

Exception in thread "main" [Link]: 10

at [Link]([Link])

Note: ArrayIndexOutOfBoundsException occurs when you try to access an index number that does not
exist.

If an error occurs, we can use try...catch to catch the error and execute some code to handle it:

Example

public class Main {

public static void main(String[ ] args) {

try {

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

[Link](myNumbers[10]);

} catch (Exception e) {

[Link]("Something went wrong.");

}} The output will be: Something went wrong.


Default Exception

Default exception usually refers to the built-in exceptions that the Java runtime throws automatically
when an error occurs. Java doesn’t have a single exception literally called “DefaultException”, but it has
a default exception handling mechanism and default runtime exceptions.

If an exception occurs and you do not handle it using try-catch, Java uses its default exception handler,
which:

 Prints the exception name


 Prints the error message
 Prints the stack trace
 Terminates the program

Example

class Test {

public static void main(String[] args) {

int a = 10 / 0; // ArithmeticException

Output

Exception in thread "main" [Link]: / by zero

at [Link]([Link])

Key Points (Exam-friendly)

 Java provides default exception handling via the JVM.


 Unhandled exceptions are processed by the default exception handler.
 It prints exception type, message, and stack trace.
 Program terminates abnormally if not handled.

Common Default (Built-in) Exceptions in Java

These are automatically thrown by Java when something goes wrong:

 Runtime Exceptions (Unchecked)


 ArithmeticException → divide by zero
 NullPointerException → accessing a null object
 ArrayIndexOutOfBoundsException → invalid array index
 ClassCastException
 NumberFormatException
Handling Default Exceptions

You can override the default behavior using try-catch.

try {

int x = 10 / 0;

} catch (ArithmeticException e) {

[Link]("Cannot divide by zero");

User Defined Exception Handling

An exception is an unwanted or unexpected event that occurs during the execution of a program, i.e., at
run time, that disrupts the normal flow of the program’s instructions. In Java, there are two types of
exceptions:

•Checked Exception: These exceptions are checked at compile time, forcing the programmer to
handle them explicitly.

• Unchecked Exception: These exceptions are checked at runtime and do not require explicit
handling at compile time.

Checked Exceptions in Java

If a method throws a checked Exception, then the exception must be handled using a try-catch block and
declared the exception in the method signature using the throws keyword.

Example

import [Link].*;

class Geeks {

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

// Getting the current root directory

String root = [Link]("[Link]");

[Link]("Current root directory: " + root);

// Adding the file name to the root directory

String path = root + "\\[Link]";

[Link]("File path: " + path);

// Reading the file from the path in the local directory


try {

FileReader f = new FileReader(path);

// Creating an object as one of the ways of taking input

BufferedReader b = new BufferedReader(f);

// Printing the first 3 lines of the file

for (int counter = 0; counter < 3; counter++)

[Link]([Link]());

[Link]();

} catch (FileNotFoundException e) {

[Link]("File not found: " + [Link]());

} catch (IOException e) {

[Link]("An I/O error occurred: " + [Link]());

Unchecked Exceptions in Java

Unchecked exception are exceptions that are not checked at the compile time. In Java, exceptions under
Error and RuntimeException classes are unchecked exceptions, everything else under throwable is
checked.

Consider the following Java program. It compiles fine, but it throws an ArithmeticException when run.
The compiler allows it to compile because ArithmeticException is an unchecked exception.

class Geeks {

public static void main(String args[]) {

// Here we are dividing by 0 which will not be caught at compile time as there is no mistake but caught
at runtime because it is mathematically incorrect

int x = 0;

int y = 10;

int z = y / x;

}
}

Note:

• Unchecked exceptions are runtime exceptions that are not required to be caught or declared in a
throws clause.

• These exceptions are caused by programming errors, such as attempting to access an index out
of bounds in an array or attempting to divide by zero.

• Unchecked exceptions include all subclasses of the RuntimeException class, as well as the
Error class and its subclasses.

Difference Between Checked and Unchecked Exceptions

Checked Exception Unchecked Exception

Unchecked exceptions are checked


Checked exceptions are checked at compile time.
at run time.

Derived from Exception. Derived from RuntimeException.

Checked exceptions must be handled using a try-catch


No handling is required.
block or must be declared using the throws keyword

Examples: IOException, SQLException, Examples: NullPointerException,


FileNotFoundException. ArrayIndexOutOfBoundsException.

throw and throws

Java throw

The throw keyword in Java is used to explicitly throw an exception from a method or any block of code.
We can throw either checked or unchecked exception. The throw keyword is mainly used to throw
custom exceptions.

Syntax: throw Instance

Where instance is an object of type Throwable (or its subclasses, such as Exception).

Example:

class Geeks {

static void fun()


{

try {

throw new NullPointerException("demo");

catch (NullPointerException e) {

[Link]("Caught inside fun().");

throw e; // rethrowing the exception

public static void main(String args[])

try {

fun();

catch (NullPointerException e) {

[Link]("Caught in main.");

Output

Caught inside fun().

Caught in main.

Java throws

throws is a keyword in Java that is used in the signature of a method to indicate that this method might
throw one of the listed type exceptions. The caller to these methods has to handle the exception using a
try-catch block.

Syntax: type method_name(parameters) throws exception_list


To prevent this compile time error we can handle the exception in two ways:

 By using try catch


 By using the throws keyword

Example

class Geeks {

static void fun() throws IllegalAccessException

[Link]("Inside fun(). ");

throw new IllegalAccessException("demo");

public static void main(String args[])

try {

fun();

catch (IllegalAccessException e) {

[Link]("Caught in main.");

Output

Inside fun().

Caught in main.
Difference Between throw and throws

The main differences between throw and throws in Java are as follows:

throw throws

It is used to declare that a method might


It is used to explicitly throw an exception.
throw one or more exceptions.

It is used inside a method or a block of code. It is used in the method signature.

It is only used for checked exceptions.


It can throw both checked and unchecked
Unchecked exceptions do not
exceptions.
require throws

The method's caller is responsible for


The method or block throws the exception.
handling the exception.

It forces the caller to handle the declared


Stops the current flow of execution immediately.
exceptions.

public void myMethod() throws


throw new ArithmeticException("Error");
IOException {}

finally clause

A finally keyword is used to create a block of code that follows a try block. A finally block of
code is always executed whether an exception has occurred or not. Using a finally block, it lets you run
any cleanup type statements that you want to execute, no matter what happens in the protected code. A
finally block appears at the end of catch block.

Example finally Block

In this example, we are using finally block along with try block. This program throws an exception and
due to exception, program terminates its execution but see code written inside the finally block
executed. It is because of nature of finally block that guarantees to execute the code.
class Demo

public static void main(String[] args)

int a[] = new int[2];

try

[Link]("Access invalid element"+ a[3]);

/* the above statement will throw ArrayIndexOutOfBoundException */

catch(ArrayIndexOutOfBoundsException e) {

[Link]("Exception caught");

finally

[Link]("finally is always executed.");

Output

Out of try

finally is always executed.

[Link]

Exception and Error Classes

Errors and exceptions are both types of throwable objects, but they represent different types of
problems that can occur during the execution of a program.

Errors are usually caused by serious problems that are outside the control of the program, such as
running out of memory or a system crash. Errors are represented by the Error class and its
subclasses. Some common examples of errors in Java include:
 OutOfMemoryError: Thrown when the Java Virtual Machine (JVM) runs out of memory.
 StackOverflowError: Thrown when the call stack overflows due to too many method
invocations.
 NoClassDefFoundError: Thrown when a required class cannot be found.

Since errors are generally caused by problems that cannot be recovered from, it's usually not
appropriate for a program to catch errors. Instead, the best course of action is usually to log the
error and exit the program.

Exceptions, on the other hand, are used to handle errors that can be recovered from within the
program. Exceptions are represented by the Exception class and its subclasses. Some common
examples of exceptions in Java include:

 NullPointerException: Thrown when a null reference is accessed.


 IllegalArgumentException: Thrown when an illegal argument is passed to a method.
 IOException: Thrown when an I/O operation fails.

Since exceptions can be caught and handled within a program, it's common to include code to
catch and handle exceptions in Java programs. By handling exceptions, you can provide more
informative error messages to users and prevent the program from crashing.

In summary, errors and exceptions represent different types of problems that can occur during
program execution. Errors are usually caused by serious problems that cannot be recovered from,
while exceptions are used to handle recoverable errors within a program.

In java, both Errors and Exceptions are the subclasses of [Link] class. Error refers
to an illegal operation performed by the user which results in the abnormal working of the
program. Programming errors often remain undetected until the program is compiled or
executed. Some of the errors inhibit the program from getting compiled or executed. Thus errors
should be removed before compiling and executing. It is of three types:

 Compile-time
 Run-time
 Logical

Whereas exceptions in java refer to an unwanted or unexpected event, which occurs during the
execution of a program i.e at run time, that disrupts the normal flow of the program’s
instructions.
Example : Run Time Error

// Java Program to Illustrate Error

// Stack overflow error via infinite recursion

class StackOverflow {

public static void test(int i)

// non-stop recursion.

if (i == 0)

return;

else {

test(i++);

public class GFG {

public static void main(String[] args)

// Testing for error by passing

[Link](5);

}
Threads
Threads allows a program to operate more efficiently by doing multiple things at the same time.

Threads can be used to perform complicated tasks in the background without interrupting the
main program.

Creating a Thread

There are two ways to create a thread.

It can be created by extending the Thread class and overriding its run() method:

Extend Syntax

public class Main extends Thread {

public void run() {

[Link]("This code is running in a thread");

Another way to create a thread is to implement the Runnable interface:

Implement Syntax

public class Main implements Runnable {

public void run() {

[Link]("This code is running in a thread");

Running Threads

If the class extends the Thread class, the thread can be run by creating an instance of the class
and call its start() method:

Extend Example

public class Main extends Thread {

public static void main(String[] args) {

Main thread = new Main();

[Link]();
[Link]("This code is outside of the thread");

public void run() {

[Link]("This code is running in a thread");

If the class implements the Runnable interface, the thread can be run by passing an instance of
the class to a Thread object's constructor and then calling the thread's start() method:

Implement Example

public class Main implements Runnable {

public static void main(String[] args) {

Main obj = new Main();

Thread thread = new Thread(obj);

[Link]();

[Link]("This code is outside of the thread");

public void run() {

[Link]("This code is running in a thread");

Differences between "extending" and "implementing" Threads

The major difference is that when a class extends the Thread class, you cannot extend any other
class, but by implementing the Runnable interface, it is possible to extend from another class as
well, like: class MyClass extends OtherClass implements Runnable.

Concurrency Problems

Because threads run at the same time as other parts of the program, there is no way to know in
which order the code will run. When the threads and main program are reading and writing the
same variables, the values are unpredictable. The problems that result from this are called
concurrency problems.
Example

A code example where the value of the variable amount is unpredictable:

public class Main extends Thread {

public static int amount = 0;

public static void main(String[] args) {

Main thread = new Main();

[Link]();

[Link](amount);

amount++;

[Link](amount);

public void run() {

amount++;

To avoid concurrency problems, it is best to share as few attributes between threads as possible.
If attributes need to be shared, one possible solution is to use the isAlive() method of the thread
to check whether the thread has finished running before using any attributes that the thread can
change.

Example

Use isAlive() to prevent concurrency problems:

public class Main extends Thread {

public static int amount = 0;

public static void main(String[] args) {

Main thread = new Main();

[Link]();

// Wait for the thread to finish

while([Link]()) {

[Link]("Waiting...");
}

// Update amount and print its value

[Link]("Main: " + amount);

amount++;

[Link]("Main: " + amount);

public void run() {

amount++;

Life Cycle:
In Java, a thread goes through several states from creation to termination. These states are
defined in the [Link] enum.

1. New State
2. Runnable State
3. Blocked State
4. Waiting State
5. Timed Waiting State
6. Terminated State
The diagram below represents various states of a thread at any instant:
Life Cycle of a Thread

There are multiple states of the thread in a lifecycle as mentioned below:

 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. When a thread lies in the new state, its code
is yet to be run and has not started to execute.
 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. It is the
responsibility of the thread scheduler to give the thread, time to run. A multi-threaded
program allocates a fixed amount of time to each individual thread. Each and every
thread get a small amount of time to run. After running for a while, a thread pauses and
gives up the CPU so that other threads can run.
 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. The thread will move from the blocked
state to runnable state when it acquires the lock.
 Waiting state: The thread will be in waiting state when it calls wait() method or join()
method. It will move to the runnable state when other thread will notify or that thread
will be terminated.
 Timed Waiting: A thread lies in a timed waiting state when it calls a method with a
time-out parameter. A thread lies in this state until the timeout is completed or until a
notification is received. For example, when a thread calls sleep or a conditional wait, it is
moved to a timed waiting state.
 Terminated State: A thread terminates because of either of the following reasons:
o Because it exits normally. This happens when the code of the thread has been
entirely executed by the program.
o Because there occurred some unusual erroneous event, like a segmentation fault
or an unhandled exception.

Thread States in Java

In Java, to get the current state of the thread, use [Link]() method to get the current state
of the thread. Java provides [Link] enum that defines the ENUM constants for
the state of a thread, as a summary of which is given below:

1. New

Thread state for a thread that has not yet started.

public static final [Link] NEW

2. Runnable

Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual
machine but it may be waiting for other resources from the operating system such as a processor.

public static final [Link] RUNNABLE


3. Blocked

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is
waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized
block/method after calling [Link]().

public static final [Link] BLOCKED

4. Waiting

Thread state for a waiting thread. A thread is in the waiting state due to calling one of the
following methods:

 [Link] with no timeout


 [Link] with no timeout
 [Link]

public static final [Link] WAITING

5. Timed Waiting

Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting
state due to calling one of the following methods with a specified positive waiting time:

 [Link]
 [Link] with timeout
 [Link] with timeout
 [Link]
 [Link]

public static final [Link] TIMED_WAITING

6. Terminated

Thread state for a terminated thread. The thread has completed execution.

public static final [Link] TERMINATED

Below example demonstrates the use of getState() method:

class MyThread implements Runnable

Thread t;

MyThread(String name)

t = new Thread(this, name);


[Link]("Child thread: " + t);

[Link]("State: " + [Link]());

[Link]();

@Override

public void run()

[Link]("State: " + [Link]());

try

for(int i = 1; i <= 3; i++)

[Link]([Link]() + ": " + i);

[Link](2000);

catch(InterruptedException e)

[Link]([Link]() + " is interrupted!");

[Link]([Link]() + " is terminated");

public class Driver

public static void main(String[] args)

{
MyThread thread1 = new MyThread("First Thread");

try

[Link]("Main thread is waiting...");

[Link](1000);

[Link]("State: " + [Link]());

[Link]();

[Link]("State: " + [Link]());

catch(InterruptedException e)

[Link]("Main thread is interrupted!");

[Link]("Main thread terminated");

Output for the above program is:

Child thread: Thread[First Thread,5,main]

State: NEW

Main thread is waiting…

State: RUNNABLE

First Thread: 1

State: TIMED_WAITING

First Thread: 2

First Thread: 3

First Thread is terminated

State: TERMINATED

Main thread terminated


Methods in Thread Class
1. start()

 Starts the execution of a thread.


 Internally calls the run() method.
 A thread can be started only once.

[Link]();

2. run()

 Contains the code that the thread will execute.


 Calling run() directly does not create a new thread.

public void run()

// task

3. sleep(long millis)

 Causes the currently executing thread to sleep for a specified time.


 Throws InterruptedException.
 Static method.

[Link](1000);

4. join()

 Makes one thread wait until another thread completes execution.


 Used for thread synchronization.

[Link]();

5. yield()

 Temporarily pauses the current thread and allows other threads of the same priority to
execute.
 Static method.

[Link]();

6. interrupt()

 Interrupts a thread that is sleeping or waiting.


 Sets the interrupt flag.
[Link]();

7. isAlive()

 Checks whether a thread is still running.

boolean status = [Link]();

8. setName(String name) / getName()

 Sets or gets the name of the thread.

[Link]("MyThread");

[Link]([Link]());

9. setPriority(int priority) / getPriority()

 Sets or gets the priority of a thread.

Priority range: 1 (MIN) to 10 (MAX)

[Link](Thread.MAX_PRIORITY);

10. currentThread()

 Returns the currently executing thread.


 Static method.

Thread t = [Link]();

11. getState()

 Returns the current state of the thread.

[Link] state = [Link]();

Commonly Used Thread Methods (Exam Focus)

Method Purpose

start() Start thread execution

run() Thread task

sleep() Pause thread

join() Wait for thread

interrupt() Interrupt thread

isAlive() Check thread status


Priority Thread
Java allows multiple threads to run concurrently, and the Thread Scheduler decides the order of
execution. Each thread has a priority between 1 and 10, which indicates its importance. Threads
with higher priority are generally preferred by the scheduler, though execution order is not
guaranteed.

 Thread.MIN_PRIORITY (1): Lowest possible priority for a thread.


 Thread.NORM_PRIORITY (5): Default priority assigned to a thread.
 Thread.MAX_PRIORITY (10): Highest possible priority for a thread.

Setting and Getting Thread Priority

We can use the following methods of the Thread class to manage thread priority:

setPriority(int newPriority): This method is used to sets the priority of a thread.

getPriority(): This method is used to returns the current priority of the thread.

class MyThread extends Thread {

public MyThread(String name){

super(name);

public void run()

[Link](

[Link]().getName()

+ " with priority "


+ [Link]().getPriority());

public class Geeks{

public static void main(String[] args){

MyThread t1 = new MyThread("Thread-1");

MyThread t2 = new MyThread("Thread-2");

MyThread t3 = new MyThread("Thread-3");

// Setting thread priorities

[Link](Thread.MIN_PRIORITY); // 1

[Link](Thread.NORM_PRIORITY); // 5

[Link](Thread.MAX_PRIORITY); // 10

// Start threads

[Link]();

[Link]();

[Link]();

Output

Thread-2 with priority 5

Thread-1 with priority 1

Thread-3 with priority 10

Explanation:

 MyThread extends Thread and overrides run(), which prints the thread’s name and
priority.
 Threads have default priority 5, which can be changed between 1–10 using setPriority().
 The code sets t1=1, t2=5, t3=10 and prints their priorities.
 On calling start(), each thread runs concurrently; higher priority may get preference, but
actual order depends on the OS thread scheduler.

 What is a thread's priority used for in Java? To control the order of thread execution
[Link]
Synchronization
What Is Synchronization?

Synchronization is the technique used to control the access of multiple threads to shared
resources. It ensures that only one thread can access a critical section of code at a time,
thus preventing conflicts, data inconsistency, or race conditions.

Why Do We Need Synchronization?

Consider a scenario where two threads try to update the same bank account balance at the
same time. If both read the same initial balance and then write their changes back without
coordination, the final result will be incorrect.

This kind of problem is known as a race condition, and synchronization prevents it by making
sure only one thread can perform a sensitive operation at a time.

Types of Thread synchronization

There are two types of thread synchronization mutual exclusive and inter-thread communication.

1. Mutual Exclusive

1. Synchronized method.

2. Synchronized block.

3. static synchronization.

2. Cooperation (Inter-thread communication in java)

Mutual Exclusive

Mutual Exclusive helps keep threads from interfering with one another while sharing data. This
can be done by three ways in java

1. by synchronized method

2. by synchronized block

3. by static synchronization

1. Synchronized Method

If you declare any method as synchronized, it is known as synchronized method. Synchronized


method is used to lock an object for any shared resource. When a thread invokes a synchronized
method, it automatically acquires the lock for that object and releases it when the thread
completes its task.

Refer [Link] till 12


page

Dead Lock

Deadlock is a situation in multithreading where two or more threads are permanently blocked
because each one is waiting for the other to release a required lock. In simple terms, threads get
stuck forever, and the program never continues.

Each thread holds a lock and waits for another lock held by a different thread.

This creates a circular wait, causing the application to freeze indefinitely.

Example: Demonstrating Deadlock Situation

public class TestThread {

public static Object Lock1 = new Object();

public static Object Lock2 = new Object();

public static void main(String args[]) {

ThreadDemo1 T1 = new ThreadDemo1();

ThreadDemo2 T2 = new ThreadDemo2();

[Link]();

[Link]();

private static class ThreadDemo1 extends Thread {

public void run() {

synchronized (Lock1) {

[Link]("Thread 1: Holding lock 1...");

try { [Link](10); }

catch (InterruptedException e) {}

[Link]("Thread 1: Waiting for lock 2...");

synchronized (Lock2) {
[Link]("Thread 1: Holding lock 1 & 2...");

private static class ThreadDemo2 extends Thread {

public void run() {

synchronized (Lock2) {

[Link]("Thread 2: Holding lock 2...");

try { [Link](10); }

catch (InterruptedException e) {}

[Link]("Thread 2: Waiting for lock 1...");

synchronized (Lock1) {

[Link]("Thread 2: Holding lock 1 & 2...");

Output

Thread 1: Holding lock 1...

Thread 2: Holding lock 2...

Thread 1: Waiting for lock 2...

Thread 2: Waiting for lock 1...

Deadlock Solution Example

Let's change the order of the lock and run of the same program to see if both the threads still wait
for each other −

public class TestThread {


public static Object Lock1 = new Object();

public static Object Lock2 = new Object();

public static void main(String args[]) {

ThreadDemo1 T1 = new ThreadDemo1();

ThreadDemo2 T2 = new ThreadDemo2();

[Link]();

[Link]();

private static class ThreadDemo1 extends Thread {

public void run() {

synchronized (Lock1) {

[Link]("Thread 1: Holding lock 1...");

try {

[Link](10);

} catch (InterruptedException e) {}

[Link]("Thread 1: Waiting for lock 2...");

synchronized (Lock2) {

[Link]("Thread 1: Holding lock 1 & 2...");

private static class ThreadDemo2 extends Thread {

public void run() {

synchronized (Lock1) {

[Link]("Thread 2: Holding lock 1...");

try {

[Link](10);
} catch (InterruptedException e) {}

[Link]("Thread 2: Waiting for lock 2...");

synchronized (Lock2) {

[Link]("Thread 2: Holding lock 1 & 2...");

Output

Thread 1: Holding lock 1...

Thread 1: Waiting for lock 2...

Thread 1: Holding lock 1 & 2...

Thread 2: Holding lock 1...

Thread 2: Waiting for lock 2...

Thread 2: Holding lock 1 & 2...

You might also like