Thread vs Runnable in Java

Naveen AnamaneniUpdated · 4 min read

Thread and Runnable are the two building blocks for creating threads. Thread is a class that represents a thread of execution and knows how to start it. Runnable is a functional interface with one method, run(), that represents a task: the work to be done. You can either extend Thread and put the work inside it, or write the work as a Runnable and give it to a Thread. In this lesson, you will learn the differences and why Runnable is the better choice.

Example: The Same Task Both Ways

Let's see an example that greets three students both ways.

Compare.java▶ Try it
public class Compare {
    static class GreetThread extends Thread {
        private final String name;
        GreetThread(String name) { this.name = name; }
        @Override
        public void run() {
            System.out.println("Thread subclass greets " + name);
        }
    }
 
    static class GreetTask implements Runnable {
        private final String name;
        GreetTask(String name) { this.name = name; }
        @Override
        public void run() {
            System.out.println("Runnable task greets " + name);
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        Thread a = new GreetThread("Navika");
        a.start();
        a.join();
 
        Runnable task = new GreetTask("Srihitha");
        Thread b = new Thread(task);
        b.start();
        b.join();
 
        task.run();
 
        Thread c = new Thread(
            () -> System.out.println("Lambda greets Advitha"));
        c.start();
        c.join();
    }
}
Output
Thread subclass greets Navika
Runnable task greets Srihitha
Runnable task greets Srihitha
Lambda greets Advitha

Explanation: Both styles do the same job. The difference is in the design: the Runnable task is separate from the thread, so the same task object can be given to a thread, called directly (task.run() ran it in the main thread), or submitted to a thread pool. The lambda is just a short Runnable.

Differences Between Thread and Runnable

Extending ThreadImplementing Runnable
TypeA classA functional interface
InheritanceUses up your one superclassYour class can still extend another
SeparationTask and thread are mixed togetherTask is separate from the thread that runs it
ReuseOne object per thread runOne task can be run by many threads or a pool
LambdasNot possible() -> ... works
ExecutorsNot designed for themSubmit directly to an ExecutorService
Thread methodsInherited (getName, interrupt...)Use Thread.currentThread()

When a Task Returns a Result

Common Mistakes

Extending Thread when you only need a task. It blocks other inheritance and mixes concerns.

Thinking Runnable creates a thread. It's only the task; a Thread or executor must run it.

Interview Corner

Which is better: extending Thread or implementing Runnable?

Implementing Runnable is generally better. It keeps the task separate from the threading mechanism, leaves the class free to extend another class, allows the same task to be run by different threads or submitted to an ExecutorService, and can be written as a lambda. Extending Thread is only appropriate when you really need to customize thread behavior itself.

Practice

  1. Easy: Rewrite a class that extends Thread as a Runnable lambda.
  2. Harder: Create one Runnable that prints the current thread's name, and run it with three differently named threads.

Quick check: Thread vs Runnable

4 questions
1What is Runnable?
2Which approach leaves your class free to extend another class?
3Does calling task.run() on a Runnable create a new thread?
4Which can be written as a lambda?

Key Takeaways

Was this tutorial helpful?

Lesson 381 of 482