Для чего используется интерфейс Runnable в Java?

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

Ответ

Интерфейс Runnable определяет задачу, которую можно выполнить в отдельном потоке. Он содержит единственный абстрактный метод run(), описывающий логику выполнения.

Ключевые характеристики и применение:

  • Основа для многопоточности: Объект Runnable передаётся в конструктор Thread или в пул потоков (ExecutorService).
  • Не возвращает результат: В отличие от Callable<V>, метод run() имеет тип void.
  • Не бросает проверяемые исключения: Исключения должны обрабатываться внутри метода run().

Примеры использования:

1. Запуск через класс Thread:

Runnable task = () -> {
    System.out.println("Выполняется в: " + Thread.currentThread().getName());
};
Thread worker = new Thread(task);
worker.start();

2. Отправка в ExecutorService (рекомендуемый способ):

ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(task); // Задача будет выполнена в одном из потоков пула
executor.shutdown();

Почему Runnable, а не Thread? Наследование от Thread связывает задачу со способом её выполнения. Runnable отделяет задачу (what) от механизма выполнения (how), что соответствует принципу единственной ответственности и позволяет гибко использовать пулы потоков.