Skip to main content

Process vs Thread

Reading Time: 7 Minutes
Difficulty: Beginner


Topic Summaryโ€‹

A process is a running program โ€” like Chrome or a Java app โ€” with its own memory space. A thread is a smaller unit of execution that lives inside a process. Multiple threads can run inside the same process, sharing memory. Threads allow a program to do multiple things at once โ€” like downloading a file while keeping the UI responsive. This is called multithreading.


What You'll Learnโ€‹

  • What a process is and what resources it has
  • What a thread is and how it relates to a process
  • Why threads are called "lightweight processes"
  • The difference between multitasking and multithreading
  • The browser analogy to understand threads intuitively

Prerequisitesโ€‹

  • No prerequisites โ€” this is the first lesson in the Multithreading module

Explanationโ€‹

What is a Process?โ€‹

A process is an independent, self-contained program in execution. When you launch your Java application, the OS creates a process for it. Each process has:

  • Its own memory space (heap, stack, code, data)
  • Its own file handles and resources
  • At least one thread (the main thread)
  • A unique Process ID (PID)

Processes are isolated โ€” one process cannot directly access another process's memory. If Chrome crashes, it doesn't crash Notepad.

Process A (Chrome) Process B (Your Java App)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Memory โ”‚ โ”‚ Memory โ”‚
โ”‚ Code โ”‚ โ”‚ Code โ”‚
โ”‚ Data โ”‚ โ”‚ Data โ”‚
โ”‚ Thread 1 โ”‚ โ”‚ main thread โ”‚
โ”‚ Thread 2 โ”‚ โ”‚ ... โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ†• OS isolation โ†•
(Processes cannot share memory directly)

What is a Thread?โ€‹

A thread is the smallest unit of execution inside a process. Multiple threads run within the same process and share:

  • The same heap memory (objects, static variables)
  • The same code and data

But each thread has its own:

  • Stack (local variables, method calls)
  • Program counter (where it is in the code)
  • Thread state (running, waiting, etc.)
Process: Java Application
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Shared memory (heap, code, static fields) โ”‚
โ”‚ โ”‚
โ”‚ Thread 1 (main) Thread 2 Thread 3 โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Stack โ”‚ โ”‚ Stack โ”‚ โ”‚ Stack โ”‚ โ”‚
โ”‚ โ”‚ PC โ”‚ โ”‚ PC โ”‚ โ”‚ PC โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why Are Threads Called "Lightweight Processes"?โ€‹

Threads are called lightweight because:

  • Creating a thread is much faster and cheaper than creating a new process
  • Threads share the process's memory โ€” no need to duplicate memory space
  • Context switching between threads is faster than between processes
  • Communication between threads is easy (shared memory) vs. processes (need IPC โ€” inter-process communication)

Multitasking vs Multithreadingโ€‹

FeatureMultitaskingMultithreading
What runs simultaneouslyMultiple processesMultiple threads in one process
MemorySeparate for each processShared among threads
CommunicationComplex (IPC)Simple (shared variables)
OverheadHighLow
ExampleChrome + Notepad + SpotifyChrome loading page while streaming music

Multitasking = running multiple programs at once (OS level)
Multithreading = running multiple tasks within one program (application level)


Why Do We Need Threads?โ€‹

Without threads, programs are single-threaded โ€” they do one thing at a time:

  1. Download file...
  2. Wait for download to finish...
  3. THEN respond to user clicks

With threads:

  1. Thread 1: Download file in background
  2. Thread 2: Keep responding to user clicks simultaneously

Real-world use cases:

  • Web servers: Each incoming request gets its own thread (Tomcat, Jetty)
  • GUIs: UI thread stays responsive while a background thread processes data
  • Games: Physics, rendering, audio run on separate threads
  • Databases: Handle multiple queries concurrently

The CPU Perspectiveโ€‹

Modern CPUs have multiple cores โ€” each core can execute one thread at a time. With 8 cores, 8 threads truly run at the same time (parallel). On a single-core CPU, the OS rapidly switches between threads โ€” so fast it appears simultaneous (concurrent, not truly parallel).

Single Core CPU Multi-Core CPU
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
T1โ”€โ”€T2โ”€โ”€T1โ”€โ”€T3โ”€โ”€T2 Core1: T1
(switching rapidly) Core2: T2
Appears parallel Core3: T3
(truly parallel)

Real-World Analogyโ€‹

Think of a web browser like Chrome:

  • The process = Chrome application running on your computer
  • Each tab = a thread (some browsers actually use separate processes per tab, but the concept holds)
  • All tabs share the same Chrome application, but each does its own thing independently
  • Tab 1 loads YouTube while Tab 2 reads Gmail while Tab 3 streams music
  • If Tab 2 freezes, Tab 1 and Tab 3 keep working

Your Java application is Chrome. Threads are the tabs. Multiple threads let your app do multiple things at once.


Code Exampleโ€‹

Example 1: Seeing the Main Threadโ€‹

public class MainThreadDemo {
public static void main(String[] args) {
// Get reference to the main thread
Thread mainThread = Thread.currentThread();

System.out.println("Thread Name: " + mainThread.getName());
System.out.println("Thread ID: " + mainThread.getId());
System.out.println("Thread Priority: " + mainThread.getPriority());
System.out.println("Thread State: " + mainThread.getState());
System.out.println("Is Alive: " + mainThread.isAlive());
System.out.println("Is Daemon: " + mainThread.isDaemon());
}
}

Outputโ€‹

Thread Name: main
Thread ID: 1
Thread Priority: 5
Thread State: RUNNABLE
Is Alive: true
Is Daemon: false

Example 2: Process vs Thread โ€” Memory Sharingโ€‹

public class MemorySharingDemo {
// Static variable โ€” shared across ALL threads
static int sharedCounter = 0;

public static void main(String[] args) throws InterruptedException {
System.out.println("Main thread: " + Thread.currentThread().getName());

Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
sharedCounter++; // Both threads access the SAME variable
System.out.println("Thread-1 incremented: " + sharedCounter);
}
});

Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
sharedCounter++; // Same shared memory!
System.out.println("Thread-2 incremented: " + sharedCounter);
}
});

t1.start();
t2.start();
t1.join();
t2.join();

System.out.println("Final shared counter: " + sharedCounter);
// Note: result may vary due to race condition โ€” we'll fix this in synchronization!
}
}

Output (approximate โ€” may vary due to thread ordering)โ€‹

Main thread: main
Thread-1 incremented: 1
Thread-2 incremented: 2
Thread-1 incremented: 3
Thread-2 incremented: 4
...
Final shared counter: 10

Example 3: Why Threads Help โ€” Simulating Concurrent Tasksโ€‹

public class WhyThreadsDemo {
// Single-threaded approach โ€” tasks run one after another
static void runSequentially() throws InterruptedException {
long start = System.currentTimeMillis();
System.out.println("=== Sequential ===");
task("Download", 2000); // 2 seconds
task("Process", 1500); // 1.5 seconds
System.out.println("Sequential done in: " +
(System.currentTimeMillis() - start) + "ms");
}

// Multi-threaded approach โ€” tasks run concurrently
static void runConcurrently() throws InterruptedException {
long start = System.currentTimeMillis();
System.out.println("\n=== Concurrent ===");

Thread t1 = new Thread(() -> {
try { task("Download", 2000); }
catch (InterruptedException e) { Thread.currentThread().interrupt(); }
});
Thread t2 = new Thread(() -> {
try { task("Process", 1500); }
catch (InterruptedException e) { Thread.currentThread().interrupt(); }
});

t1.start();
t2.start();
t1.join();
t2.join();

System.out.println("Concurrent done in: " +
(System.currentTimeMillis() - start) + "ms");
}

static void task(String name, int ms) throws InterruptedException {
System.out.println(name + " started by " + Thread.currentThread().getName());
Thread.sleep(ms);
System.out.println(name + " finished!");
}

public static void main(String[] args) throws InterruptedException {
runSequentially(); // ~3500ms
runConcurrently(); // ~2000ms (concurrent!)
}
}

Outputโ€‹

=== Sequential ===
Download started by main
Download finished!
Process started by main
Process finished!
Sequential done in: 3502ms

=== Concurrent ===
Download started by Thread-0
Process started by Thread-1
Process finished!
Download finished!
Concurrent done in: 2001ms

Common Mistakesโ€‹

  • โŒ Mistake: Thinking threads are completely independent programs โ†’ โœ… Fix: Threads are part of the same process โ€” they share memory, which is both powerful and dangerous (race conditions)
  • โŒ Mistake: Thinking Java is always single-threaded โ†’ โœ… Fix: Java programs always have multiple threads โ€” the JVM starts main, GC, Finalizer threads at minimum
  • โŒ Mistake: Thinking more threads always means faster โ†’ โœ… Fix: Too many threads cause overhead from context switching โ€” there's an optimal number based on CPU cores and task type
  • โŒ Mistake: Confusing thread and process โ†’ โœ… Fix: Process = an entire running program with its own memory. Thread = a task running inside that program, sharing the program's memory

Best Practicesโ€‹

  • Use threads for tasks that can run independently and in parallel
  • Be aware that shared memory between threads requires synchronization (we'll cover this later)
  • Don't create thousands of bare threads โ€” use thread pools (ExecutorService) for production
  • Daemon threads (background threads) automatically die when the main thread finishes
  • Use Thread.currentThread().getName() for debugging to know which thread is running

Interview Questionsโ€‹

Q: What is the difference between a process and a thread?
A: A process is an independent program in execution with its own memory space. A thread is a lightweight unit of execution inside a process โ€” multiple threads share the process's heap memory. Process creation is expensive; thread creation is cheap.

Q: Why are threads called lightweight processes?
A: Threads are cheaper to create and switch between than processes. They share the parent process's memory space so no memory duplication is needed. Context switching between threads is faster than between processes.

Q: What is the difference between multitasking and multithreading?
A: Multitasking involves running multiple processes (programs) simultaneously at the OS level. Multithreading involves running multiple threads within a single process โ€” multiple tasks within one program.

Q: How many threads does a Java program start with?
A: At minimum, the JVM starts several threads: the main thread (your program's entry point), the Garbage Collector thread, the Finalizer thread, and JVM internal threads.


Quick Revisionโ€‹

โœ” Process = running program, own memory, isolated from other processes
โœ” Thread = task inside a process, shares process memory
โœ” Threads are lightweight โ€” cheaper to create and switch than processes
โœ” Threads share heap but each has its own stack and program counter
โœ” Multithreading = multiple threads in one process doing concurrent work
โœ” Java always has a main thread โ€” plus JVM background threads


  • Creating Threads (Lesson 2)
  • Thread Lifecycle (Lesson 3)
  • Synchronization (Lesson 4)
  • ExecutorService

Next Lessonโ€‹

Lesson 2 โ€” Creating Threads