Какой интерфейс нужен для работы с потоками?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Интерфейсы для работы с потоками в Java
Поток (Thread) — это наименьшая единица выполнения в Java. Для работы с потоками используется несколько интерфейсов и классов, каждый из которых подходит для разных задач.
Основной интерфейс: Runnable
Runnable — это самый фундаментальный интерфейс для многопоточности.
@FunctionalInterface
public interface Runnable {
void run();
}
Особенности:
- Имеет только один метод:
run() - Не возвращает результат (void)
- Не выбрасывает checked исключения
- Functional interface (с Java 8 можно использовать lambda)
// Способ 1: Создать класс, реализующий Runnable
public class MyTask implements Runnable {
@Override
public void run() {
System.out.println("Выполняется в отдельном потоке");
}
}
// Способ 2: Использовать lambda (Java 8+)
Runnable task = () -> System.out.println("Lambda task");
// Создание и запуск потока
Thread thread = new Thread(task);
thread.start(); // Запустить поток
Интерфейс Callable<T>
Callable — это улучшенная версия Runnable, которая может возвращать результат и выбрасывать исключения.
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Отличия от Runnable:
- Возвращает результат типа V
- Может выбросить checked exception
- Используется с ExecutorService
// Callable с возвращаемым значением
Callable<Integer> task = () -> {
System.out.println("Выполняется задача");
return 42;
};
// Запуск через ExecutorService
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(task);
Integer result = future.get(); // Блокирует до получения результата
System.out.println("Результат: " + result); // Выведет 42
executor.shutdown();
Интерфейс Future<V>
Future — это интерфейс для представления результата асинхронного вычисления.
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
Ключевые методы:
get()— получить результат (блокирует поток)isDone()— проверить, завершена ли задачаcancel()— отменить выполнение
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
Thread.sleep(1000);
return "Результат готов";
});
if (!future.isDone()) {
System.out.println("Задача ещё выполняется");
}
String result = future.get(2, TimeUnit.SECONDS); // Ждать max 2 секунды
System.out.println(result);
executor.shutdown();
Интерфейс Executor
Executor — это интерфейс для управления пулом потоков.
public interface Executor {
void execute(Runnable command);
}
Интерфейс ExecutorService
ExecutorService — это расширение Executor с поддержкой управления жизненным циклом.
public interface ExecutorService extends Executor {
void shutdown();
boolean isShutdown();
boolean isTerminated();
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
// ... другие методы
}
Примеры использования:
// 1. FixedThreadPool (фиксированное количество потоков)
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " выполняется потоком " + Thread.currentThread().getName());
});
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
// 2. CachedThreadPool (создаёт потоки по необходимости)
ExecutorService executor = Executors.newCachedThreadPool();
// 3. SingleThreadExecutor (один поток)
ExecutorService executor = Executors.newSingleThreadExecutor();
// 4. ScheduledExecutorService (планирование задач)
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.schedule(() -> System.out.println("Задача"), 5, TimeUnit.SECONDS);
scheduler.scheduleAtFixedRate(() -> System.out.println("Повторяется"), 0, 2, TimeUnit.SECONDS);
scheduler.shutdown();
Сравнение интерфейсов
| Интерфейс | Возвращаемое | Исключения | Использование |
|---|---|---|---|
| Runnable | void | Нет (unchecked только) | Thread, Executor |
| Callable<V> | V | Да (checked) | ExecutorService, Future |
| Future<V> | V | Да | Получение результата async задачи |
| Executor | - | - | Управление потоками |
| ExecutorService | Future | - | Управление пулом потоков |
Практический пример: асинхронная обработка данных
public class DataProcessor {
private ExecutorService executor = Executors.newFixedThreadPool(4);
public Future<String> processDataAsync(String data) {
return executor.submit(() -> {
// Долгая операция
Thread.sleep(2000);
return "Обработано: " + data;
});
}
public void processMultiple(List<String> items) throws ExecutionException, InterruptedException {
List<Future<String>> futures = items.stream()
.map(this::processDataAsync)
.collect(Collectors.toList());
for (Future<String> future : futures) {
System.out.println(future.get());
}
}
public void shutdown() {
executor.shutdown();
}
}
Java 21+: Virtual Threads (Project Loom)
// Старый способ (heavy threads)
ExecutorService executor = Executors.newFixedThreadPool(100);
// Java 21+: Virtual Threads (легче, быстрее)
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 10000; i++) {
executor.submit(() -> {
System.out.println("Virtual thread");
});
}
executor.shutdown();
Итого
Основные интерфейсы для работы с потоками:
- Runnable — базовый интерфейс, не возвращает результат
- Callable<T> — возвращает результат, может выбросить исключение
- Future<V> — представляет асинхронный результат
- ExecutorService — управляет пулом потоков
Для современной разработки рекомендуется использовать ExecutorService вместо прямого создания Thread, так как это обеспечивает лучшую производительность и управление ресурсами.