Creating Threads
About
In Java, threads can be created and managed using multiple approaches. Each approach has its use cases and trade-offs. Some of the approaches are given below.
1. Extending the Thread
Class
Thread
ClassThe simplest way to create a thread is by extending the
Thread
class.The
run()
method is overridden to define the thread's behavior.A new thread is started using the
start()
method.
Example:
Limitations:
Java does not support multiple inheritance, so extending
Thread
prevents extending other classes.Better to use the
Runnable
interface if we need more flexibility.
2. Implementing the Runnable
Interface
Runnable
InterfaceInstead of extending
Thread
, theRunnable
interface can be implemented.The
run()
method is implemented inside the class.The thread is started using
Thread
class.
Example:
Advantages:
Allows the class to extend other classes (unlike extending
Thread
).Encouraged in multi-threaded environments where tasks can be separated from threads.
3. Using Callable
and Future
(Return Value from Thread)
Callable
and Future
(Return Value from Thread)The
Callable<T>
interface (fromjava.util.concurrent
) allows a thread to return a result.The
Future<T>
interface is used to retrieve the result of the thread execution.
Example:
Advantages:
Unlike
Runnable
,Callable
allows returning values and throwing exceptions.
4. Using Anonymous Class
Instead of defining a separate class, threads can be created using an anonymous class.
Example:
Use Case:
Useful for quick thread creation without creating separate classes.
5. Using Lambda Expressions (Java 8+)
Java 8 introduced lambda expressions, making it even more concise to create threads.
Advantages:
Reduces boilerplate code for single-method interfaces like
Runnable
.
6. Using ThreadPoolExecutor
(Efficient Thread Management)
ThreadPoolExecutor
(Efficient Thread Management)Instead of creating a new thread every time, thread pools reuse existing threads.
ThreadPoolExecutor
is a low-level API for managing thread pools.
Example:
Advantages:
Reduces overhead of creating/destroying threads frequently.
Better resource management for high-load applications.
7. Using ForkJoinPool
(Parallel Computing)
ForkJoinPool
(Parallel Computing)The Fork-Join framework is useful for parallel computing by dividing tasks into smaller subtasks.
Example:
Use Case:
Suitable for divide-and-conquer algorithms like parallel recursion and large dataset processing.
8. Using Virtual Threads
(Java 19+)
Virtual Threads
(Java 19+)Virtual Threads (introduced in Java 19) allow lightweight, high-performance thread execution.
Unlike OS threads, millions of virtual threads can be created without performance issues.
Example:
Advantages:
Extremely lightweight, highly scalable, and does not consume OS resources like traditional threads.
Ideal for handling highly concurrent workloads efficiently.
Comparison of Thread Creation Methods
Extending Thread
Low
No
Simple tasks
Low
Implementing Runnable
Medium
No
Basic concurrency
Low
Using Callable
& Future
Medium
Yes
Background tasks needing results
Medium
Using Anonymous Class
Medium
No
Quick thread execution
Low
Using Lambda Expressions
Medium
No
Shorter syntax
Low
Using ThreadPoolExecutor
High
No
Managing large tasks efficiently
Medium
Using ForkJoinPool
High
Yes
Parallel processing, recursion
High
Using Virtual Threads
High
No
Highly scalable concurrency
Low
Main Thread and New Thread Running Parallelly
After creating a new thread, the main thread continues to execute concurrently (parallelly) with the newly created thread.
Example
How it Works?
The main thread starts execution from
main()
.It creates a new thread (
MyThread
) and starts it usingstart()
.The new thread (
run()
) runs independently while the main thread continues executing its own tasks.Both threads execute concurrently, and the CPU switches between them using the scheduler.
Concurrency vs. Parallelism
Concurrency:
Multiple threads/tasks overlap in execution but may not execute at the exact same instant.
The CPU switches between threads rapidly, giving the illusion of simultaneous execution.
Occurs in single-core or multi-core systems.
Parallelism:
Multiple threads/tasks execute at the exact same time on different CPU cores.
Requires a multi-core processor to truly run tasks simultaneously.
Why "Both threads execute concurrently" and not "parallelly"?
In Java, when we create a new thread, it does not guarantee that it will run on a separate core.
Java threads are managed by the JVM and the OS scheduler, which may time-share them on a single CPU.
If we have a single-core CPU, the threads can only run concurrently by switching back and forth.
If we have a multi-core CPU, the threads may run truly in parallel, but this depends on OS scheduling.
Example of Concurrency vs. Parallelism
1. Concurrent Execution (Single-Core CPU)
(Threads switch rapidly, but only one runs at a time.)
2. Parallel Execution (Multi-Core CPU)
(Both threads run simultaneously on different CPU cores.)
Last updated
Was this helpful?