Threads and Runnable

Process vs Thread

A process is a running program with its own memory. A thread is a path of execution inside a process. All threads of a process share the same heap (objects) but each has its own stack (local variables, method calls). Every Java program starts with one thread called main.

JVM process
┌──────────────────────────────────────────────┐
│ Heap (shared objects)                        │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│ │ main     │ │ worker-1 │ │ worker-2 │  ...  │
│ │ stack    │ │ stack    │ │ stack    │       │
│ └──────────┘ └──────────┘ └──────────┘       │
└──────────────────────────────────────────────┘

Three Ways to Create a Thread

WayCodeNotes
Extend Threadclass Worker extends Thread { public void run() {...} }uses up your only superclass
Implement Runnablenew Thread(() -> ...)preferred: task separate from thread
Executor / virtual threadexecutor.submit(task), Thread.ofVirtual().start(task)what real apps use (next modules)

start() and join()

Example

start() creates a new thread that calls run(). join() waits for that thread to finish. Here each worker writes into its own array slot and main prints after joining, so the output order is fixed.

public class Main {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Running in: " + Thread.currentThread().getName());
        long[] partialSums = new long[4];
        Thread[] workers = new Thread[4];

        for (int i = 0; i < 4; i++) {
            final int part = i;
            workers[i] = new Thread(() -> {
                long sum = 0;
                for (int n = part * 250_000 + 1; n <= (part + 1) * 250_000; n++) sum += n;
                partialSums[part] = sum;
            }, "worker-" + i);
            workers[i].start();
        }
        for (Thread t : workers) t.join();

        long total = 0;
        for (int i = 0; i < 4; i++) {
            System.out.println(workers[i].getName() + " sum = " + partialSums[i]);
            total += partialSums[i];
        }
        System.out.println("Total 1..1,000,000 = " + total);
    }
}

Output

Running in: main
worker-0 sum = 31250125000
worker-1 sum = 93750125000
worker-2 sum = 156250125000
worker-3 sum = 218750125000
Total 1..1,000,000 = 500000500000

run() is Not start()

Note: Calling thread.run() directly does not create a new thread: the code runs on the current thread like a normal method call. Always call start(). Calling start() twice on the same thread throws IllegalThreadStateException.