Ответ
Да, java.lang.Runnable — это функциональный интерфейс. Он определяет контракт для задачи, которая может быть выполнена потоком (Thread).
Ключевые характеристики:
- Содержит единственный абстрактный метод
void run(). - Не принимает параметров и не возвращает результат.
- Является основой для многопоточности и параллельного выполнения задач.
- Может быть представлен лямбда-выражением или ссылкой на метод.
Примеры использования:
-
Создание потока с лямбдой:
Runnable task = () -> { System.out.println("Задача выполняется в потоке: " + Thread.currentThread().getName()); }; new Thread(task).start(); -
Передача в 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. Всё гениальное — просто, как три копейки.