В чем разница между Thread и Runnable в Java?

«В чем разница между Thread и Runnable в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Thread — это класс, который представляет собой поток выполнения. Runnable — это функциональный интерфейс, задача (run()), которую может выполнить поток.

Ключевые отличия:

Аспект Thread (класс) Runnable (интерфейс)
Наследование Наследование от Thread занимает слот единственного родительского класса. Реализация Runnable не мешает наследовать другой класс.
Разделение ответственности Совмещает в себе и задачу (код в run()), и механизм выполнения (поток). Определяет только задачу. Управление потоком — отдельно.
Переиспользование Задача привязана к конкретному экземпляру Thread. Один экземпляр Runnable можно выполнить в разных потоках (Thread, пулы).
Рекомендация Наследовать Thread обычно не рекомендуется. Предпочтительный подход согласно best practices.

Пример реализации через Runnable (рекомендуется):

// Задача отделена от механизма выполнения
Runnable task = () -> {
    System.out.println("Выполняется в потоке: " + Thread.currentThread().getName());
};

// Запуск задачи в новом потоке
Thread thread = new Thread(task, "MyThread-1");
thread.start();

// Та же задача может быть отправлена в ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(task);

Пример наследования Thread (не рекомендуется):

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Выполняется в: " + getName());
    }
}
new MyThread().start(); // Задача и поток неразделимы.

Вывод: Всегда предпочитайте Runnable (или Callable) для определения задачи. Это обеспечивает лучшую архитектуру, гибкость и совместимость с современными concurrency API (ExecutorService, ForkJoinPool).