Multithreaded Programming in Java
1. Introduction
A thread is the smallest unit of execution within a process.
Multithreading is a programming technique that allows multiple parts of a program (threads) to
run concurrently.
Multithreading in Java is a feature that allows multiple tasks to run concurrently within the same
program. Instead of executing one task at a time, Java enables parallel execution using
lightweight threads.
This makes applications more efficient, faster and responsive in real-world scenarios like servers,
games and chat systems.
Key Features of Multithreading
A thread is the smallest unit of execution in Java
Threads share the same memory space but run independently.
Java provides the Thread class and Runnable interface to create threads.
Multithreading ensures better CPU utilization by executing tasks simultaneously.
Synchronization is needed to prevent data inconsistency when threads share resources
2. Creating Threads in Java
Java provides strong support for multithreading through the [Link] class and the
[Link] [Link] are two common ways to create threads:
(a) By Extending the Thread Class
1. Create a class that extends Thread.
2. Override the run() method to define the thread task.
3. Create an object of the class and call start() to run the thread.
Syntax: Example Program:
class ClassName extends Thread { class MyThread extends Thread {
public void run() { public void run() {
[Link]("Thread is
// task for the thread
running: " +
} [Link]().getName());
}
public static void main(String[] args) { }
ClassName t1 = new ClassName(); //
create object public class Main {
public static void main(String[] args) {
[Link](); // start the thread
MyThread t1 = new MyThread();
}
[Link](); // Starts a new thread
} }
}
(b) By Implementing the Runnable Interface
1. Create a class that implements Runnable.
2. Override the run() method.
3. Create a Thread object and pass the Runnable object to it.
4. Call start() on the Thread.
Syntax: Example:
class MyRunnable implements Runnable { class MyRunnable implements Runnable {
public void run() { public void run() {
[Link]("Runnable thread is [Link]("Runnable thread is
running: " + running: " +
[Link]().getName()); [Link]().getName());
} }
} }
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
Thread t1 = new Thread(new Thread t1 = new Thread(new
MyRunnable()); MyRunnable());
[Link](); [Link]();
}} }}
Advantages of Multithreading in Java
1. Improved Performance: Multiple tasks can run simultaneously, reducing execution time.
2. Efficient CPU Utilization: Threads keep the CPU busy by running tasks in parallel.
3. Resource Sharing: Threads within the same process share memory and resources, avoiding
duplication.
5. Better User Experience: Smooth execution of tasks like file downloads, animations, and real-
time updates.
Example: Suppose a restaurant kitchen where multiple chefs are working simultaneously on different
dishes. This setup ensures faster service and better CPU (chef) utilization, just like threads in Java
Example: Restaurant Kitchen (Extending Thread)
class CookingTask extends Thread { Thread t2 = new CookingTask("Salad");
private String task; Thread t3 = new CookingTask("Dessert");
Thread t4 = new CookingTask("Rice");
CookingTask(String task) {
[Link] = task; [Link]();
} [Link]();
[Link]();
public void run() { [Link]();
[Link](task + " is being prepared }
by " + }
[Link]().getName());
} Output
} Salad is being prepared by Thread-1
Rice is being prepared by Thread-3
public class Restaurant {
Dessert is being prepared by Thread-2
public static void main(String[] args) {
Pasta is being prepared by Thread-0
Thread t1 = new CookingTask("Pasta");
Life Cycle of Thread
During its lifetime, a thread transitions through several states, they are:
1. New State
2. Active State
3. Waiting/Blocked State
4. Timed Waiting State
5. Terminated State
Working of Thread States
1. New State: By default, a thread will be in a new state, in this state, code has not yet started execution.
2. Active State: When a thread calls the start() method, it enters the Active state, which has two sub-
states:
Runnable State: The thread is ready to run but is waiting for the Thread Scheduler to give it CPU
time. Multiple runnable threads share CPU time in small slices.
Running State: When the scheduler assigns CPU to a runnable thread, it moves to the Running
state. After its time slice ends, it goes back to the Runnable state, waiting for the next chance to run.
3. Waiting/Blocked State: a thread is temporarily inactive, it may be in the Waiting or Blocked state:
Waiting: If thread T1 needs to use a camera but thread T2 is already using it, T1 waits until T2
finishes.
Blocked: If two threads try to use the same resource at the same time, one may be blocked until
the other releases it.
When multiple threads are waiting or blocked, the Thread Scheduler decides which one gets CPU based
on priority.
4. Timed Waiting State: Sometimes threads may face starvation if one thread keeps using the CPU for a
long time while others keep waiting.
For example: If T1 is doing a long important task, T2 may wait indefinitely. To avoid this, Java provides
the Timed Waiting state, where methods like sleep() allow a thread to pause only for a fixed time. After
the time expires, the thread gets a chance to run.
5. Terminated State: A thread enters the Terminated state when its task is finished or it is explicitly
stopped. In this state, the thread is dead and cannot be restarted. If you try to call start() on a terminated
thread, it will throw an exception.
Thread Class Methods in Java
The Thread class (in [Link] package) provides many methods to create, control, and manage threads.
Category Method Use / Purpose Result
start() Starts a new thread Calls run() in a new thread
Basic
run() Defines the thread’s task Executes task inside thread
sleep(ms) Pauses thread temporarily Thread enters Timed Waiting
join() One thread waits for another Sequential execution
Control
Hints scheduler to switch
yield() Another thread may run
threads
isAlive() Checks if thread is running Returns true / false
getName() / setName() Get or set thread name Helps identify threads
Info getPriority() / Higher priority = more CPU
Get/set priority (1–10)
setPriority() chance
Returns current executing
currentThread() Useful for debugging
thread
interrupt()
Interrupts sleeping/waiting Throws
thread InterruptedException
Interrupt isInterrupted() Checks interruption flag Returns status
Checks & clears interrupt
interrupted() Returns status and resets flag
flag
stop() Forcibly kills thread Unsafe termination
Deprecated suspend() Pauses thread (holds lock) Unsafe (may cause deadlock)
(Avoid)
resume() Resumes suspended thread Unsafe continuation
Makes thread wait & release
wait() Thread enters Waiting state
lock
Communication notify()
Wakes one waiting thread Thread becomes Runnable
(Object class)
All waiting threads become
notifyAll() Wakes all waiting threads
Runnable
Thread Synchronization in Java
1. What is Synchronization?
Synchronization is a way to control access to shared resources in multithreaded programming.
When two or more threads access a shared resource (like a variable, object, or file), data
inconsistency may occur.
Synchronization ensures only one thread can access the resource at a time → prevents race
conditions.
2. Why Synchronization is Needed?
Example problem (without synchronization):
class Counter {
int count = 0;
void increment() {
count++; // shared resource
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
Thread t1 = new Thread(() -> {
for(int i=0; i<1000; i++) [Link]();
});
Thread t2 = new Thread(() -> {
for(int i=0; i<1000; i++) [Link]();
});
[Link](); [Link]();
[Link](); [Link]();
[Link]("Final Count = " + [Link]);
}
}
Java Exception Handling
Exception
An exception is an unwanted or unexpected event that occurs during program execution.
It disrupts the normal flow of the program.
Example: dividing a number by zero → ArithmeticException.
In other words, Exception Handling in Java is one of the powerful mechanism to handle the
runtime errors so that the normal flow of the application can be maintained.
Types of Exceptions
1. Checked Exceptions
o Checked at compile-time.
o Must be handled using try-catch or declared with throws.
o Example: IOException, SQLException.
2. Unchecked Exceptions
o Checked at runtime.
o Mostly due to programming errors.
o Example: ArithmeticException, NullPointerException.
3. Errors
o Serious problems that cannot be handled by the program.
o Example: OutOfMemoryError, StackOverflowError.
Keywords in Exception Handling
1. try – block of code where exception might occur.
2. catch – handles the exception.
3. finally – block that always executes (cleanup code).
4. throw – used to explicitly throw an exception.
5. throws – declares exceptions in method signature.
Syntax:
try {
int data = 10 / 0; // may throw exception
} catch (ArithmeticException e) {
Advantages
[Link]("Cannot divide by zero!");
Example Program:
import [Link].*;
class Geeks {
public static void main(String[] args)
{
int n = 10;
int m = 0; The Output is ArithmeticEXception: / by Zero
int ans = n / m;
Divide By Zero
[Link]("Answer: " + ans);
}
}
import [Link].*;
class Addition {
public static void main(String[] args)
{
int n = 10;
int m = 0;
try { Output
// Code that may throw an exception Error: Division by zero
int ans = n / m; is not allowed!
[Link]("Answer: " + ans);
} Program continues after
catch (ArithmeticException e) { handling the exception.
// Handling the exception
[Link](
"Error: Division by zero is not allowed!");
ArrayIndexOutOfBound
} Exception
finally {
[Link](
"Program continues after handling the exception.");
}
Different Between Error and Exception
Exception = Recoverable problems (handled with try-catch).
Error = Serious problems (not handled, program fails).
Java Applets
A Java Applet is a Java program that runs inside a web browser. An Applet is embedded in an HTML
file using <applet> or <objects> tags. Applets are used to make the website more dynamic and
entertaining. Applets are executed in a sandbox for security, restricting access to local system resources.
Key Points:
Applet Basics: Every applet is a child/subclass of the [Link] class.
Not Standalone: Applets don’t run on their own like regular Java programs. They need a web
browser or a special tool called the applet viewer (which comes with Java).
No main() Method: Applets don't start with main() method.
Display Output: Applets don't use [Link]() for displaying the output, instead they use
graphics methods like drawString() from the AWT (Abstract Window ToolKit) .
Java Applet Life Cycle
The below diagram demonstrates the life cycle of Java Applet:
It is important to understand the order in which the various methods shown in the above image are
called.
When an applet begins, the following methods are called, in this sequence:
o init( )
o start( )
o paint( )
When an applet is terminated, the following sequence of method calls takes place:
o stop( )
o destroy( )
Let’s look more closely at these methods.
1. init( ): The init( ) method is the first method to be called. This is where you should initialize
variables. This method is called only once during the run time of your applet.
2. start( ): The start( ) method is called after init( ). It is also called to restart an applet after it has been
stopped.
Note: init( ) is called once i.e. when the first time an applet is loaded whereas start( ) is called each
time an applet’s HTML document is displayed onscreen. So, if a user leaves a web page and comes
back, the applet resumes execution at start( )
3. paint( ): The paint( ) method is called each time an AWT-based applet’s output must be redrawn.
This situation can occur for several reasons. For example, the window in which the applet is running
may be overwritten by another window and then uncovered. Or the applet window may be minimized
and then restored.
paint( ) is also called when the applet begins execution. Whatever the cause, whenever the applet
must redraw its output, paint( ) is called.
The paint( ) method has one parameter of type Graphics. This parameter will contain the graphics
context, which describes the graphics environment in which the applet is running. This context is
used whenever output to the applet is required.
paint() is the only method among all the methods mention above (which is parameterized).
This method is crucial for updating or redrawing the visual content of the applet.
Example:
public void paint(Graphics g)
{
// Drawing a string on the applet window
// g is an object reference of class Graphic.
[Link]("Hello, Applet!", 50, 50);
}
Now the below Question Arises:
In the prototype of paint() method, we have created an object reference without creating its object.
But how is it possible to create object reference without creating its object?
Ans. Whenever we pass object reference in arguments then the object will be provided by its caller
itself. In this case the caller of paint() method is browser, so it will provide an object. The same
thing happens when we create a very basic program in normal Java programs. For Example:
public static void main(String []args) {
}
Here we have created an object reference without creating its object but it still runs because it’s
caller, i.e. JVM will provide it with an object.
4. stop( ): The stop( ) method is called when a web browser leaves the HTML document containing
the applet, when it goes to another page.
For example: When stop( ) is called, the applet is probably running. You should use stop( ) to
suspend threads that don’t need to run when the applet is not visible. You can restart them when
start( ) is called if the user returns to the page.
5. destroy( ): The destroy( ) method is called when the environment determines that your applet
needs to be removed completely from memory. At this point, you should free up any resources the
applet may be using. The stop( ) method is always called before destroy( ).
Example program for Draw a Simple Face using Applet
import [Link];
import [Link].*;
// <applet code="SmileyApplet" width=300 height=300></applet>
public class SmileyApplet extends Applet {
public void paint(Graphics g) {
// Face outline
[Link]([Link]);
[Link](50, 50, 200, 200);
// Eyes
[Link]([Link]);
[Link](100, 110, 20, 20); // Left eye
[Link](180, 110, 20, 20); // Right eye
// Smile (arc)
[Link](100, 150, 100, 50, 0, -180);
}
}
Execution Steps (for 16 marks):
1. Applet lifecycle → JVM loads Applet, calls init(), then paint().
2. Drawing face → fillOval(50,50,200,200) creates circular yellow face.
3. Drawing eyes → Two smaller filled ovals represent left & right eyes.
4. Drawing smile → drawArc(100,150,100,50,0,-180) creates a semi-circle (smile).
5. Rendering → Applet viewer or browser paints graphics on canvas.