Multithreading in Java
Expert Answer & Key Takeaways
A comprehensive guide to Java Multithreading: Creating threads, thread lifecycle, synchronization, and the Runnable interface.
Multithreading in Java
Multithreading is a core feature of Java that allows concurrent execution of two or more parts of a program for maximum utilization of the CPU. Each part of such a program is called a Thread.
1. Thread vs. Process
- Process: A process is a program in execution. It is 'heavyweight' because it has its own separate memory area (address space). Switching between processes is slow.
- Thread: A thread is a lightweight sub-process; the smallest unit of processing. Multiple threads share the same memory area allocated to their parent process. Switching between threads is much faster.
2. The Thread Lifecycle
A thread in Java goes through several states during its lifetime (managed by the Thread Scheduler):
- New: The thread is created (
Thread t = new Thread();) but not yet started. - Runnable: After
t.start()is called. The thread is ready to run and waiting for CPU time. - Running: The CPU is actively executing the thread's
run()method. - Non-Runnable (Blocked/Waiting): The thread is alive but cannot run because it is waiting for a resource (like I/O or a lock) or
sleep()was called. - Terminated (Dead): The
run()method has finished executing. The thread is dead and cannot be restarted.
3. How to Create a Thread
There are two ways to create a thread in Java:
3.1 By Extending the Thread Class
You create a class that inherits from
java.lang.Thread and override its run() method.class MyThread extends Thread {
public void run() {
System.out.println("Thread is running...");
}
}
public class Main {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start(); // This automatically calls the run() method in a new call stack
}
}3.2 By Implementing the Runnable Interface (Recommended)
Since Java does not support multiple inheritance, extending the
Thread class limits your ability to extend another class. Implementing Runnable is the preferred approach.class MyRunnable implements Runnable {
public void run() {
System.out.println("Thread using Runnable is running...");
}
}
public class Main {
public static void main(String[] args) {
MyRunnable m1 = new MyRunnable();
Thread t1 = new Thread(m1); // Pass the runnable to a new Thread object
t1.start();
}
}4. Important Thread Methods
start(): Starts the execution of the thread. JVM calls therun()method.run(): Contains the actual logic the thread will execute.sleep(milliseconds): Pauses the currently executing thread for a specified time.join(): Waits for a thread to die. If threadAcallsB.join(),Awill stop executing untilBfinishes.setPriority(int): Changes the priority of the thread (1 is MIN, 5 is NORM, 10 is MAX).
5. Synchronization
When multiple threads try to access the same shared resource (like a variable or a file) simultaneously, it can lead to data inconsistency. This is called a Race Condition.
- Solution: We use the
synchronizedkeyword. It locks the resource so that only one thread can access it at a time. Other threads must wait until the lock is released.
synchronized void printData() {
// Only one thread can execute this block at a time
}Course4All Editorial Board
Verified ExpertSubject Matter Experts
Comprising experienced educators and curriculum specialists dedicated to providing accurate, exam-aligned preparation material.
Pattern: 2026 Ready
Updated: Weekly
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.