Module 5
Module 5
MODULE 5
Dr Divya Meena Sundaram
1
Sr. Asst Prof. Grade 1
SCOPE
VIT-AP University
CONCURRENT
PROGRAMMING
Concurrent programming is a programming paradigm that deals with the execution of multiple tasks
or processes concurrently, allowing for better utilization of computing resources and improved
performance.
Each process has its own memory space and resources. Threads within a process share the same memory space.
Processes are independent and isolated from each other. Threads can easily communicate and share data with each other.
Inter-process communication (IPC) is required for sharing data Threads can directly access shared data and resources.
between processes.
Context switching between processes incurs higher overhead. Context switching between threads is faster and lightweight.
Processes have higher memory overhead. Threads have lower memory overhead compared to processes.
Suitable for CPU-bound tasks that can benefit from parallelism. Suitable for I/O-bound tasks and concurrent operations.
Provides true parallelism, as each process can run on a separate Provides concurrency within a single CPU core.
CPU core simultaneously.
Each process has its own address space, making memory Threads share the same address space, requiring synchronization
isolation simpler. mechanisms to avoid race conditions.
Processes are more robust, as an error or crash in one process A thread error or crash can potentially affect the entire process.
does not affect others.
MULTI-THREADED
PROGRAMMING
Multi-threaded programming involves writing code that can execute multiple threads concurrently within a
single program.
Although, it is a powerful tools for designing and implementing concurrent applications, it also introduces
challenges such as thread synchronization, deadlock avoidance, and efficient resource management.
utilizing multiple threads for parallel execution, while concurrent programming encompasses a broader set
of strategies for managing and coordinating concurrent tasks or processes, not limited to just threads.
PROCESS VS. THREAD
Processes and threads are fundamental concepts in concurrent programming
Process Thread
• A process can be seen as an instance of a running • A thread is a lightweight unit of execution within a
program. process.
• It represents an independent and isolated unit of • Threads share the same memory space and system
execution, with its own memory space, file descriptors, resources of the process they belong to.
and system resources. • They have their own program counter, stack, and local
• Each process has its own address space, allowing it to variables, but they can access shared data
run independently of other processes. • Multiple threads within a process can execute
• Processes communicate with each other using inter- concurrently and communicate with each other through
process communication (IPC) mechanisms such as shared data.
pipes or sockets.
Processes Threads
Context switching between processes incurs more Context switching between threads is faster and
overhead. lightweight.
Processes provide isolation and can achieve true Threads allow for concurrency within a single process.
parallelism.
Creation and termination of processes are more costly. Creation and termination of threads are relatively
inexpensive.
Processes have higher memory overhead. Threads have lower memory overhead compared to
processes.
Processes are less likely to cause interference or Threads accessing shared resources need
conflicts. synchronization.
Processes can run on separate CPU cores for true Threads run within the same process, utilizing
parallelism. concurrency.
LIFE CYCLE OF A THREAD
The life cycle of a thread refers to the various states that a thread can exist in during its lifetime. A thread
goes through different states as it is created, starts execution, runs, waits for resources, and eventually
terminates.
1. New State
When a thread is created but has not yet started its execution, it is in the "new" state.
In this state, the necessary system resources, such as memory and thread stack, are allocated to the thread, but it has
The thread remains in the new state until the start() method is invoked on it.
2. Runnable State
When the start() method is called on a thread, it transitions to the "runnable" state.
In the runnable state, the thread is eligible to run, but it may or may not be currently executing, depending on the
The thread scheduler of the operating system determines when to start the thread's execution and which runnable
In this state, the thread is actively using the CPU resources to execute its instructions.
A thread remains in the running state until it is paused by the scheduler, either due to a time slice expiration or a
become available.
For example, a thread might enter the blocked state when it requests a lock that is currently held by another thread.
While in the blocked state, the thread gives up the CPU and does not consume CPU resources until the condition it is
The thread can transition back to the runnable state when the blocking condition is resolved, such as when it acquires
class's stop() method (which is generally discouraged due to potential issues with resource cleanup).
The resources associated with the terminated thread, such as memory and file handles, are released by the operating
system.
TRANSITIONS BETWEEN
THREAD STATES
A thread starts in the new state when it is created.
When the start() method is invoked, the thread transitions from the new state to the runnable state.
From the runnable state, the thread can be scheduled to enter the running state.
While running, a thread can transition back to the runnable state if its time slice expires or a higher-
A thread enters the blocked state when it needs to wait for a certain condition or resource.
When the blocking condition is resolved, the thread transitions from the blocked state back to the
runnable state.
Finally, when a thread completes its execution or is explicitly terminated, it enters the terminated state
(highest priority).
The Thread class provides constants for three priority levels: MIN_PRIORITY (1),
NORM_PRIORITY (5), and MAX_PRIORITY (10).
The thread scheduler in the operating system determines the order in which threads are allocated
However, thread scheduling is ultimately controlled by the operating system, and the exact behavior
time.
Threads can be used to perform complicated tasks in the background without interrupting
methods to create and perform operations on a thread. Thread class extends Object class and implements
Runnable interface.
1. Thread()
2. Thread(String name)
3. Thread(Runnable r)
2. public void start(): starts the execution of the thread.JVM calls the run() method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing thread to sleep (temporarily cease execution)
for the specified number of milliseconds.
5. public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
10. public Thread currentThread(): returns the reference of currently executing thread.
11. public int getId(): returns the id of the thread.
14. public void yield(): causes the currently executing thread object to temporarily pause and allow other threads to execute.
19. public void setDaemon(boolean b): marks the thread as daemon or user thread.
21. public boolean isInterrupted(): tests if the thread has been interrupted.
22. public static boolean interrupted(): tests if the current thread has been interrupted.
1. BY EXTENDING THREAD
CLASS
Step 1: Override the run( ) method available in Thread class. This method provides an entry
point for the thread and you will put your complete business logic inside this method.
Step 2: Once Thread object is created, you can start it by calling start() method, which executes
a call to run( ) method.
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running.");
}
}
public class ThreadExample {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
1. BY IMPLEMENTING A RUNNABLE
INTERFACE
Step 1: As a first step, you need to implement a run() method provided by a Runnable interface. This
method provides an entry point for the thread and you will put your complete business logic inside this
method.
Step 2: As a second step, you will instantiate a Thread object using the following constructor
where, threadObj is an instance of a class that implements the Runnable interface and threadName is the
name given to the new thread.
Step 3: Once a Thread object is created, you can start it by calling start() method, which executes a call to
run( ) method.
class MyRunnable implements Runnable {
public void run() {
System.out.println("Thread is running.");
}
}
public class ThreadCreationExample2 {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable); // Create a Thread object and pass the MyRunnable instance
thread.start();
}
}
public class SleepExample {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
class MyRunnable implements Runnable {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread is running: " + i);
try {
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
} } }
Extending the Thread class Implementing the Runnable interface
Pros: Pros:
• Simplicity: Extending the Thread class allows you • Flexibility: Implementing the Runnable interface
to define the task directly within the subclass. allows you to separate the task from the threading
Cons: mechanism, providing more flexibility in your code
• Limited flexibility: By extending the Thread class, structure.
you cannot extend any other classes since Java does • Enhanced reusability: Since the task is
not support multiple inheritance. encapsulated within a separate class, it can be easily
• Reduced reusability: Since your code is tightly reused in different threading scenarios.
coupled with the Thread class, it may limit code Cons:
reuse in other contexts. • Slightly more complex: Implementing the Runnable
interface involves creating a separate class and
passing it to a Thread object, adding a bit of
complexity compared to extending the Thread class.
THREAD
SYNCHRONIZATION
Synchronization in Java is the capability to control the access of multiple threads to any shared
resource.
Java Synchronization is better option where we want to allow only one thread to access the shared
resource.
1. Process Synchronization
2. Thread Synchronization
THREAD SYNCHRONIZATION
There are two types of thread synchronization mutual exclusive and inter-thread communication.
1. Mutual Exclusive
Synchronized method.
Synchronized block.
Static synchronization.
programming.
A lock provides a mechanism to control access to shared resources, allowing only one thread
It ensures that multiple threads can safely access shared data without causing data corruption
or inconsistencies.
PROBLEM WITHOUT
SYNCHRONIZATION
1. JAVA SYNCHRONIZED
METHOD
If you declare any method as synchronized, it is known as synchronized method.
When a thread invokes a synchronized method, it automatically acquires the lock for that
method.
Suppose we have 50 lines of code in our method, but we want to synchronize only 5 lines, in
If we put all the codes of the method in the synchronized block, it will work same as the
synchronized method.
3. STATIC SYNCHRONIZATION