Multithreading in Java
Multithreading in Java is the ability of a program to run several parts of itself at the same time. Each independent path of execution is called a thread. A web server uses threads to serve many users at once; a music app plays audio on one thread while the screen stays responsive on another. Every Java program starts with one thread, the main thread, and can create more. In this lesson, you will learn what a thread is, how it differs from a process, and why multithreading is useful.
Process vs Thread
A process is a running program, such as your browser or a Java application. A thread is a lightweight unit of work inside a process.
| Process | Thread | |
|---|---|---|
| What it is | A running program | A path of execution inside a process |
| Memory | Its own separate memory | Shares the process's heap with other threads |
| Own resources | Memory, files, handles | Only its own stack and program counter |
| Creation cost | Heavy | Light |
| Communication | Hard (files, sockets, pipes) | Easy (shared objects), but needs care |
| A crash | Usually doesn't affect other processes | An uncaught error in one thread can corrupt shared data |
Why Use Threads
- Responsiveness: a slow task, such as a download, runs in the background while the program keeps responding.
- Speed on multi-core CPUs: independent work can run on several cores at the same time.
- Waiting in parallel: many network or disk waits can overlap instead of happening one after another.
- Simpler design for independent tasks: each task can be written as a straightforward sequence of steps.
Example: Two Threads Working at Once
Let's see an example where the main thread starts a second thread and both do work. Each thread waits between steps, so the lines come out in a predictable order.
public class TwoThreads {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("worker: step " + i);
pause(200);
}
});
worker.start();
pause(100);
for (int i = 1; i <= 3; i++) {
System.out.println("main: step " + i);
pause(200);
}
worker.join();
System.out.println("Both threads finished");
}
static void pause(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}worker: step 1
main: step 1
worker: step 2
main: step 2
worker: step 3
main: step 3
Both threads finishedExplanation: new Thread(...) creates a thread whose job is the lambda, and start() begins running it alongside the main thread. Because the worker starts 100 milliseconds ahead and both pause 200 milliseconds between steps, their lines take turns. join() makes the main thread wait until the worker has finished before printing the last line.
Common Mistakes
Calling run() instead of start(). The code then runs in the current thread; no new thread is created.
Expecting threads to run in a fixed order. Without coordination, their timing is unpredictable.
Sharing changeable data between threads without care. It causes race conditions, covered in "Synchronization in Java".
Interview Corner
What is the difference between a process and a thread?
A process is an executing program with its own address space and resources. A thread is a unit of execution within a process; all threads of a process share its heap memory and resources, while each has its own stack and program counter. Threads are cheaper to create and switch between and can communicate through shared objects, but that sharing requires synchronization to avoid race conditions.
Practice
- Easy: Start a thread that prints the numbers 1 to 5 with a short pause, while the main thread prints "Main is still running".
- Harder: Start two threads that each count to 3 with different pause lengths, and
joinboth before printing "Done".
Key Takeaways
Was this tutorial helpful?