Threads and Runnable

Multithreading · lesson 1 of 38 · 3 min read

Start real threads with Runnable, and see why start() and run() are not the same thing.

Open this lesson in the learning hub

Key points

  • A thread is a separate line of execution. Your program already has one, called main.
  • Runnable is the work. Thread is the worker that runs it. Keep those two ideas apart.
  • start() spawns a new thread. run() is an ordinary method call on the current thread. That mix-up is the classic first bug.
  • join() blocks until that thread finishes. Without it, main can end before the workers do.
  • Each platform thread costs about 1 MB of stack. A few hundred is fine; thousands need a pool or virtual threads.

Example

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> System.out.println(Thread.currentThread().getName() + " is working");

        Thread t1 = new Thread(task, "worker-1");
        Thread t2 = new Thread(task, "worker-2");

        t1.start();   // start() = new thread
        t2.start();
        task.run();   // run() = plain method call, still on main

        t1.join();    // wait for it to finish
        t2.join();
        System.out.println("main: both workers done");
    }
}

start() creates a thread. run() just calls a method.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Multithreading course, and every lesson in it is listed on the Multithreading contents page.