Этот вопрос проверяет знание стандартных способов запуска потоков и понимание различий между ними.
В Java есть несколько способов создать поток. Основные — это наследование от Thread и реализация Runnable. Также часто используются Callable и ExecutorService. На практике предпочтение отдаётся работе через пул потоков.
Java предлагает несколько уровней абстракции для работы с потоками — от низкоуровневых до более удобных и безопасных.
Перед перечислением важно отметить, что ручное управление потоками используется всё реже.
ThreadПодходит для простых примеров, но используется редко.
class MyThread extends Thread {
public void run() {
// логика потока
}
}
new MyThread().start();
Недостатки:
Нельзя наследоваться от другого класса
Смешивается логика задачи и потока
RunnableБолее гибкий и предпочтительный вариант.
Runnable task = () -> {
// логика задачи
};
new Thread(task).start();
CallableИспользуется, когда нужен результат выполнения или обработка исключений.
Возвращает значение
Может выбрасывать checked-исключения
ExecutorServiceСовременный и рекомендуемый способ.
Управляет пулом потоков
Упрощает масштабирование
Снижает количество ошибок
ExecutorService executor = Executors.newFixedThreadPool(4);
// executor.submit(task);
В реальных проектах почти всегда используют ExecutorService, так как он безопаснее и удобнее ручного управления потоками.