Ответ
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).