Other Parts of This Series:

Java Thread Programming (Photo Credit: Medium)
N.B: Please read the following concepts for better understanding before continue reading this article.
β Threads, Asynchronicity, Concurrency, Parallelism
What is a Thread?
- A thread = a lightweight unit of execution within a process.
- A Java process (JVM instance) always starts with main thread.
What is Multi-Threading?
- Multithreading means executing multiple threads concurrently in a single program.
- Normally Java programs run on single thread called main thread.
- But you can create more threads to run tasks concurrently (not necessarily in parallel, depends on CPU cores & scheduling).
π Benefit: Run multiple things at once (e.g., UI stays responsive while downloading data).
Benefits of Multithreading:
- Better CPU utilization
- Faster execution of independent tasks
- Efficient resource sharing
- Makes real-time apps responsive
- Handles multiple tasks simultaneously (like UI + background download)
- Essential for concurrent systems, gaming, real-time applications
Thread Creation Process
There are several ways to create thread in Java. Some of them are below:
- Extending Thread:
|
|
- Implementing Runnable / Callable:
Prefer Runnable if your class needs to extend another class.
- With Lambda (modern style):
Thread Lifecycle
A thread goes through states:
- NEW β after creation (new Thread(…)).
- RUNNABLE β after calling start().
- RUNNING β when CPU picks it.
- WAITING / TIMED_WAITING / BLOCKED β when waiting or locked.
- TERMINATED β after finishing run().
π We can inspect state with t.getState().
Common Java Thread Methods
start()
Starts a new thread and internally calls run()
.
|
|
run()
The code executed when the thread runs (donβt call it directly β use start()
).
sleep(ms)
Pause current thread for given milliseconds.
|
|
join()
Wait for another thread to finish.
|
|
currentThread()
Returns the currently executing thread.
|
|
getName()
/setName()
Get or set thread name.
getId()
Returns unique thread ID.
|
|
getState()
Returns the state (NEW, RUNNABLE, BLOCKED, WAITING, etc.).
|
|
isAlive()
Checks if thread is still running.
|
|
yield()
Hints scheduler to let other threads run.
|
|
interrupt()
Sends an interrupt signal to a thread.
|
|
isInterrupted()
/interrupted()
Check if a thread was interrupted.
|
|
setPriority(int)
/getPriority()
Suggest CPU scheduling priority (1
=MIN, 5
=NORM, 10
=MAX).
|
|
setDaemon(boolean)
Mark a thread as daemon (ends when all user threads finish).
|
|
activeCount()
Returns number of active threads in current group.
|
|
β οΈ Best practice: use interrupt() + check Thread.interrupted() instead of stop() (unsafe).
Shared Data Problem (Race Conditions)
Threads share memory β risk of corruption if multiple threads write at same time.
Example (bad):
|
|
Synchronization (Solution)
- synchronized keyword: Only one thread can enter the method at a time.
Example:
- Locks: More flexible than synchronized.
Example:
- Volatile: Ensures visibility of variable changes across threads, but doesnβt guarantee atomicity.
Example:
|
|
Communication Between Threads
- wait() / notify()
- BlockingQueue (preferred!)
Executor Framework (Java 5+)
Manages thread pools automatically. Better than creating threads manually.
Example:
Futures & CompletableFuture
Async programming with callbacks.
Example:
More Modern Java Concurrency
- Virtual Threads (Java 21+)
Thousands of lightweight threads β ideal for servers.
Example:
- Scoped Values (Java 25)
Safer alternative to ThreadLocal.
Example:
- Structured Concurrency (Java 25, preview)
Treat related tasks as one unit, easier cancellation & error handling.
Example: