All 15 Concurrency & Threads questions
More in Concurrency & Threads
Advertisement
Back to results for “Concurrency & Threads”
Java › Concurrency & Threads

What are the two primary ways to create a thread in Java (extending Thread versus implementing Runnable), and which is generally preferred?

Beginner

Answer

You can either extend the Thread class directly (overriding run()) or implement the Runnable functional interface (defining run() and passing an instance to a new Thread) -- implementing Runnable is generally preferred since Java doesn't support multiple inheritance (extending Thread uses up your one available superclass slot, preventing your class from extending anything else), and it more cleanly separates the task's logic (Runnable) from the mechanism of running it as a thread (Thread), also enabling that same task logic to be submitted to a thread pool via ExecutorService without needing an actual Thread subclass at all.
// Preferred: implementing Runnable
Runnable task = () -> System.out.println("Running in: " + Thread.currentThread().getName());
Thread thread = new Thread(task);
thread.start();

// Less preferred: extending Thread directly
class MyThread extends Thread {
    @Override
    public void run() { System.out.println("Running"); }
}
Real-world example A codebase consistently uses Runnable (often as a lambda) submitted to an ExecutorService rather than manually creating and managing raw Thread objects, both for the flexibility Runnable provides and to benefit from a thread pool's reuse and resource management rather than creating a new OS thread for every single task.

Common follow-ups: What happens if you call run() directly instead of start() -- does it actually run on a new thread?;Why can a class only extend Thread OR implement Runnable, not benefit from both approaches simultaneously?