Runnable — это интерфейс в Java?

Ответ

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

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

  • Содержит единственный абстрактный метод void run().
  • Не принимает параметров и не возвращает результат.
  • Является основой для многопоточности и параллельного выполнения задач.
  • Может быть представлен лямбда-выражением или ссылкой на метод.

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

  1. Создание потока с лямбдой:

    Runnable task = () -> {
        System.out.println("Задача выполняется в потоке: " + Thread.currentThread().getName());
    };
    new Thread(task).start();
  2. Передача в ExecutorService:

    ExecutorService executor = Executors.newFixedThreadPool(2);
    executor.submit(() -> System.out.println("Асинхронное выполнение"));
    executor.shutdown();

Важно: Для задач, которые должны возвращать результат или бросать проверяемые исключения, следует использовать интерфейс Callable<V>.

Ответ 18+ 🔞

О, смотри-ка, классика жанра подъехала! java.lang.Runnable — это ж тот самый дедушка, с которого вся многопоточная движуха в Java началась. Интерфейс, блядь, проще пареной репы, но без него нихуя бы не работало.

Суть его, если по-простому, — это бумажка с одной-единственной подписью: «я, нижеподписавшийся, обязуюсь выполнить метод run()». И всё! Больше от тебя нихуя не требуется. Ни параметров на вход, ни результата на выход — просто сделай что-то. Идеально для фоновых задачек, которые надо просто запустить и забыть, типа «прочитай файл», «отправь запрос» или «посчитай цифры, пока я кофе пью».

Вот смотри, как это выглядит в жизни, без всей этой официозной хуйни:

Пример первый, на коленке:

// Это ж можно лямбдой записать, одной строчкой, ёпта!
Runnable почиститьКартошку = () -> {
    System.out.println("Начинаю драть шкуру с картофелин в потоке: " + Thread.currentThread().getName());
    // Тут твоя логика, можешь хоть до посинения считать
};
// И поехали!
new Thread(почиститьКартошку).start();

Пример второй, для серьёзных дядек с пулами потоков:

// Создаём бригаду из двух работяг (потоков)
ExecutorService бригада = Executors.newFixedThreadPool(2);
// Кидаем им задание — и свободны!
бригада.submit(() -> System.out.println("Бригада асинхронно пашет, начальник отдыхает"));
// После работы — гасим свет.
бригада.shutdown();

А теперь, внимание, важный момент, чтобы не облажаться! Если твоей задаче нужно вернуть результат (например, сумму вычислений) или она может швырнуть проверяемое исключение (типа IOException), то Runnable — не твой вариант. Тут уже нужен его более умный братан — java.util.concurrent.Callable<V>. Он уже умеет и результат возвращать, и исключения кидать. А Runnable — это такой скромный труженик, который делает своё дело молча, в тени, и ни на что не претендует. Чистая рабочая лошадка, блядь!

Короче, запомни: хочешь просто запустить — бери Runnable. Хочешь запустить и получить ответ — ищи Callable. Всё гениальное — просто, как три копейки.