Java Multithreading
By- Anupam Shukla
Improves CPU utilization by performing multiple
operations simultaneously.
Efficient for I/O-bound and high-latency
operations.
Why Ideal for tasks like gaming, web services, data
processing.
Multithreading?
Provides better responsiveness in interactive
applications.
Thread-A thread is a lightweight unit of execution
within a program. Think of it like a mini-program
running inside your main program.
Thread vs Process
Creating •
•
1. Extending Thread class:
class MyThread extends Thread { public void run() { ... } }
Threads in
• 2. Implementing Runnable interface:
• class MyRunnable implements Runnable { public void
run() { ... } }
Java • 3. Lambda with Runnable (Java 8+): new Thread(() -> { ...
}).start();
Why we prefer Runnable?
Not possible
Possible
Thread
Lifecycle
Explained
• New → Runnable → Running → Blocked/Wai ng → Terminated.
• start(): moves thread to Runnable.
• run(): thread logic.
• join(): waits for another thread to finish.
• sleep(): pauses thread temporarily.
Note- When a java program starts,one thread begins running immediately,which is called main
[Link] thread is responsible for executing the main method.
getState- is used to know the status of the thread
class MyThread extends Thread {
public void run() {
[Link]("Running
Example: thread...");
Basic }
}
Thread
public class Test {
Code public static void main(String[] args) {
new MyThread().start();
}
}
Daemon • Daemon threads are those threads which work in
background.
Threads • Syntax- [Link](true)
Prevents race conditions and
ensures thread safety.
Use synchronized methods
or blocks.
Synchronization
in Java
Example: synchronized(this)
{ ... }
Only one thread can access a
synchronized block at a time.
Code:
Synchronization
Example
Used for inter-thread communication.(threads
often need to communicate with each other to
accomplish a task).
wait(): pauses for amount of time and releases
lock when notified.
wait()
notify() notify(): wakes up one waiting thread.
notifyAll()
notifyAll(): wakes up all waiting threads.
Must be inside synchronized context.
Locks are of two types –
LOCKS 1)Intrinsic (Synchronised lock)
2)Extrinsic Lock(More control when read and
write)
Read • ReadWrite lock gives comfortabilibly and allows
multiple thread to read resources until anyone is
Write Lock writing to it.
ReentrantLock
• ReentrantLock from [Link] is an
implementation of lock interface.
• Explicit lock/unlock gives better control.
• tryLock() for timeout support.
• Use finally block to ensure unlock().
Synchronised VS ReadWrite Lock VS Reentrant Lock
Feature Synchronized ReentrantLock ReadWriteLock
Type Intrinsic (built-in) Explicit lock Explicit read/write locks
Reentrancy Yes Yes Yes
Yes (new Yes
Fairness Option No
ReentrantLock(true)) (ReentrantReadWriteLock(true))
Interruptible Locking No Yes Yes
Yes
Timed Lock No Yes
(tryLock(timeout))
Multiple Readers
No No Yes
Allowed
Complex locking
Use Case Simple locking High read, low write ratio
needs
Auto Unlock on
Yes No (needs finally) No (needs finally)
Exception
Volatile • Ensures visibility of variable changes
across threads.
Keyword
• Prevents thread-local caching.
• Use for flags, not for atomic operations.
• Example: volatile boolean running = true;
[Link]() in Java
• The tryLock() method is part of the Lock interface in Java's
[Link] package. It attempts to acquire the lock without
blocking. If the lock is available, it acquires it and returns true; otherwise, it
returns false immediately.
• Key Points:
• Non-blocking: Unlike [Link](), tryLock() does not wait indefinitely for
the lock.
• Returns a boolean: It returns true if the lock is acquired, otherwise
false.
• Can be used with timeout: The overloaded method tryLock(long time,
TimeUnit unit) waits for the specified time before giving up.
finally- generally we release resources in finally.
[Link]()- same as synchronized- it will wait till we get the lock .So, we generally
don’t use it
• Part of [Link] package.
Atomic Variables • Operations like incrementAndGet() are atomic.
• No need for explicit synchronization.
• Use AtomicInteger, AtomicLong, etc.
AtomicInteger is a thread-safe class in [Link] that
supports lock-free, atomic operations on an int value — such as
incrementing, decrementing, or updating — without using synchronized.
• Collection of pre-initialized thread that are
ThreadPools ready to execute the task.
Better alternative to creating
threads manually.
[Link](n),
submit(), shutdown().
ExecutorService
& Thread Pool
Manages thread lifecycle
efficiently.
Supports Callable and Future for
results.
Create fixed thread pool
Executor is basically a Utility class
newSingleThreadExecutor – in this only one thread executor will come.
Note-Earlier what we write in run we will write in submit .
Executor. Shutdown()-> it stops accepting any submit action
and start shutdowning the process.
Factorial • If we want each thread to take 3 numbers then
in newFixedThreadPool we will write 3 instead of
program 9.
Executor • Executor contains only execute method and
didn’t had shutdown method.
Callable • Callable returns a value.
and •
•
[Link]() waits for result.
[Link](Callable) returns
Future.
Future • Useful for parallel computation.
Future give result of submit action
• [Link](true) means if task is going on or
Future stopped doesn’t matter ,cancel it .
• [Link](false) means if task is not running
methods then it will not interrupt . if future not running then
cancel it.
If u want to return something • Executor service- We studied two types of
then use callable . And if u don’t method –
want to return any thing then
use runnable. • Submit method of runnable
• Submit method of callable.
[Link]()=>collection of tasks so it
uses list .It can take all tasks and then execute that.
Starvation • Starvation: thread denied access due to
priority.
• Deadlock(blocked forever): two/more
& threads waiting for each [Link] typically
occurs when two or more threads have
Deadlock •
circular dependencies on set of locks.
Avoid by lock ordering, timeout
strategies.
One thread produces,
another consumes.
Use BlockingQueue or
Producer- wait/notify for coordination.
Consumer
Prevents overflow/underflow
Problem in shared buffer.
Ensures synchronization and
cooperation.
Multithreading improves performance and
responsiveness.
Use synchronization to avoid race conditions.
ExecutorService simplifies thread management.
Summary Apply volatile, atomic variables, and locks wisely.
Mastering multithreading ensures scalable Java
applications.
Anything is called threadsafe when multiple threads
are trying to access but we don’t get unexpected result.