« Threads and Multithreading concepts
Threads and multithreading form the backbone of concurrent programming in Java, allowing
your applications to perform multiple tasks seemingly simultaneously.
What is a Thread?
- Lightweight Process: A thread is like a mini-process within a process, representing a single
sequence of execution.
- Sharing Resources: Threads within the same process share the same memory space and
resources, enabling efficient communication and data exchange.
- Independent Execution: Each thread runs independently, with its own execution path and
stack
Multithreading:
- Concurrent Execution: Multithreading allows multiple threads to execute concurrently
within a single process. While it may appear as if tasks are happening simultaneously, the
threads are actually taking turns utilizing the CPU.
- Multiprocessing and multithreading, both are used to achieve multitasking. But we use
multithreading than multiprocessing because threads share a common memory area. They
don't allocate separate memory area so saves memory, and context-switching between the
threads takes less time than process
- Benefits of Multithreading:
- Responsiveness: Keeps the application responsive even when performing time-
consuming tasks.
~ Resource Utilization: Efficiently utilizes CPU resources by switching between threads
when one is waiting for I/O or other operations.
- Performance: Improves application performance, especially on multi-core processors.
- Independent: It doesn't block the user because threads are independent and you can
perform multiple operations at same time
-Exception Handling: Threads are independent so it doesn't affect other threads if
exception occur in a single thread
Creating Threads in Jaya:
There are two primary ways to create threads in Java:
1. Extending the Thread Class:
~ Define a class that extends the “Thread” class.
- Override the *run()’ method with the code you want the thread to execute.= Create an instance of your class and call the *start()" method to initiate the thread,
2. Implementing the Runnable Interface:
- Define a class that implements the ‘Runnable’ interface.
- Implement the ‘run()’ method with the desired thread code.
- Create an instance of your class and pass it to a “Thread’ object's constructor,
- Start the thread using the “start()’ method on the “Thread” object.
Thread Synchronization and Communication:
- Race Conditions: Concurrent access to shared resources can lead to unpredictable results
and errors.
- Synchronization Mechanisms: Java provides mechanisms like synchronized methods,
synchronized blocks, and locks to ensure that only one thread can access a shared resource at
atime, preventing race conditions.
= Inter-thread Communication: Mechanisms like wait(), notify(), and notifyAll() enable
threads to communicate and coordinate their activities.
Thread Pool
- Managing Threads: Creating and destroying threads repeatedly can be inefficient.
- Thread Pool: A pool of pre-created threads ready to execute tasks.
- Benefits: Improves performance and resource utilization by reusing threads and avoiding
the overhead of thread creation,
+ Thread Life Cycle (Thread States)
A thread in Java goes through various stages during its lifetime, from creation to termination.
Understanding this lifecycle is crucial for effectively managing and working with threads in
your applications.
According to sun, there is only 4 states in thread life cycle in java new, runnable, non-
runnable and terminated. There is no running state. But for better understanding the threads,
we are explaining it in the 5 statesstart() sleepdone, 1/0
complete,lockavailable,
resume , notify
Runnable
Non-Runnable
ae”
sleep, blockon /O, wait
forlock, suspend, wait
‘The Life Cycle Stages:
1. New:
- The thread is created using either the “Thread’ class constructor or by implementing the
*Runnable* interface and passing it to a ‘Thread’ object.
At this stage, the thread is not yet alive and hasn't started execution,
2. Runnable:
- The thread enters the runnable state when the “start()° method is invoked on the “Thread”
object.
- It's now eligible to be picked by the JVM for execution. However, it may not necessarily
be running immediately, as the JVM schedules threads based on priority and other factors.
3. Running:
- The thread is ai
ly executing its code within the “run()’ method.
- It continues to run until one of the following occurs:
) The ‘run()’ method completes its execution naturally.b) An exception is thrown within the "run() method, causing the thread to terminate
abruptly.
©) The thread is interrupted by another thread.
Blocked/Waiting:
~A thread enters the blocked or waiting state when it's temporarily inactive, waiting for a
specific event or resource.
- This can occur due to various reasons, such as:
a) Waiting for /O operations to complete
b) Acquiring a lock on a synchronized resource that is currently held by another thread.
©) Calling methods like “sleep)’ or ‘wait()’ which explicitly put the thread in a waiting
state.
5. Timed Waiting:
- Similar to the blocked/waiting state, but with a specified time limit.
- The thread waits for a certain amount of time or until a specific event occurs,
- Examples include using methods like ‘sleep(millis)’ or ‘wait(millis)’
6. Terminated:
- The thread reaches the terminated state when its "run()’ method completes execution or
it's terminated due to an exception or interruption,
- Once terminated, a thread cannot be restarted,
Key Points:
~ A thread can transition between these states’ multiple times during its lifetime.
- The JVM manages the scheduling and execution of threads, and the exact timing of state
transitions can be unpredictable.
- Understanding the lifecycle helps identify potential issues like deadlocks or starvation
where threads are perpetually blocked or waiting for resources.
- Using appropriate synchronization and thread management techniques is crucial for
ensuring smooth and efficient concurrent execution.Thread Sleep
In Java, the ‘Thread.sleep()’ method allows you to pause the execution of the current thread
for a specified amount of time. This can be useful for various purposes, such as:
= Introducing delays: You might need to wait for a certain event or resource to become
available before proceeding.
- Simulating real-world timing: In simulations or games, you can use sleep to control the pace
of actions or events.
- Rate limiting: Sleep can be used to control the frequency of operations, preventing overload
or excessive resource usage.
How to Use ‘Thread.sleep(”
try {
Thread sleep(milliseconds); // Pause for the specified time in milliseconds
} catch (InterruptedException e) {
1/ Handle the exception if the sleep is interrupted
Arguments: * Milliseconds: The amount of time to sleep, specified in milliseconds.
Important Points:
- Checked Exception: ‘Thread.sleep()’ throws an ‘InterruptedException’ if the sleeping
thread is interrupted before the specified time has elapsed. You must handle this exception
using a try-catch block.
- Thread State: While sleeping, the thread is in a "blocked" state and does not consume CPU
resources.
- Precision: The actual sleep duration might not be exactly the same as the specified
milliseconds due to factors like system scheduling.
Alternatives to “Thread sleep()
-TimeUnit’ class: Provides methods for converting time units and sleeping with more
readable code:
TimeUnit. SECONDS sleep(5); // Sleep for 5 seconds
* Object.wait()’ and ‘Object notify()'/ Object. notify AII(": Used for thread synchronization
and communication, where one thread waits for a specific condition to be met before
continuing.Example:
class A extends Thread
{ public void run()
{ for(int i=1si {
for (int i=0;1 {
for (inti=0;1
{
for (int i=0;1 {
for (int i= 0; 1