public interface Future<V> {
// Отменяет выполнение задачи
boolean cancel(boolean mayInterruptIfRunning);
// Возвращает true, если задача была отменена до ее завершения
boolean isCancelled();
// Возвращает true, если задача завершилась
boolean isDone();
// Блокирует текущий поток и ждет завершения задачи, затем возвращает результат
V get() throws InterruptedException, ExecutionException;
// Блокирует текущий поток и ждет завершения задачи в течение указанного времени
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
} import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) {
// Создаем пул потоков
ExecutorService executor = Executors.newFixedThreadPool(2);
// Создаем задачу, которая будет выполняться асинхронно
Future<String> future = executor.submit(() -> {
// Имитация долгой операции
Thread.sleep(2000);
return "Результат асинхронной операции";
});
// Пока задача выполняется, мы можем делать другую работу
System.out.println("Задача запущена, делаем другую работу...");
try {
// Получаем результат (блокирующий вызов)
String result = future.get(); // ← Этот вызов заблокирует поток до завершения задачи
System.out.println("Результат: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown(); // ← Важно закрыть ExecutorService
}
}
} import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureCreation {
public static void main(String[] args)
throws ExecutionException, InterruptedException {
// 1. Создание уже завершенного CompletableFuture с результатом
CompletableFuture<String> completedFuture =
CompletableFuture.completedFuture("Готовый результат");
// 2. Создание CompletableFuture с помощью лямбда-выражения
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// Имитация долгой операции
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Результат асинхронной операции";
});
// 3. Создание CompletableFuture с использованием ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture<String> futureWithExecutor = CompletableFuture.supplyAsync(() -> {
// Долгая операция
return "Результат с использованием ExecutorService";
}, executor);
// Получение результатов
System.out.println(completedFuture.get());
System.out.println(future.get());
System.out.println(futureWithExecutor.get());
executor.shutdown();
}
}
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureCallbacks {
public static void main(String[] args)
throws ExecutionException, InterruptedException {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// Имитация долгой операции
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Результат операции";
});
// thenApply() - преобразует результат и возвращает новый CompletableFuture
CompletableFuture<String> transformedFuture = future.thenApply(result -> {
return "Преобразованный результат: " + result.toUpperCase();
});
// thenAccept() - потребляет результат, ничего не возвращая
CompletableFuture<Void> consumedFuture = future.thenAccept(result -> {
System.out.println("Потребленный результат: " + result);
});
// thenRun() - выполняет действие после завершения, не используя результат
CompletableFuture<Void> runFuture = future.thenRun(() -> {
System.out.println("Операция завершена!");
});
// Вывод результатов
System.out.println(transformedFuture.get());
// Ждем завершения всех операций
consumedFuture.get();
runFuture.get();
}
}
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureComposition {
public static void main(String[] args)
throws ExecutionException, InterruptedException {
// thenCompose() - плоская композиция (flatMap)
CompletableFuture<String> composedFuture =
CompletableFuture.supplyAsync(() -> {
return "Результат первой операции";
}).thenCompose(firstResult -> {
// Используем результат первой операции для создания второй
return CompletableFuture.supplyAsync(() -> {
return firstResult + " + Результат второй операции";
});
});
// thenCombine() - комбинирует два независимых CompletableFuture
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Результат операции 1";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Результат операции 2";
});
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {
return result1 + " + " + result2;
});
// allOf() - ждет завершения всех CompletableFuture
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(
CompletableFuture.supplyAsync(() -> { System.out.println("Задача 1 завершена"); return null; }),
CompletableFuture.supplyAsync(() -> { System.out.println("Задача 2 завершена"); return null; }),
CompletableFuture.supplyAsync(() -> { System.out.println("Задача 3 завершена"); return null; })
);
// anyOf() - ждет завершения хотя бы одного CompletableFuture
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(
CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return "Результат из задачи 1";
}),
CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
return "Результат из задачи 2";
})
);
// Вывод результатов
System.out.println("Результат thenCompose: " + composedFuture.get());
System.out.println("Результат thenCombine: " + combinedFuture.get());
allOfFuture.get(); // ← Ждем завершения всех задач
System.out.println("Все задачи завершены!");
System.out.println("Результат anyOf: " + anyOfFuture.get()); // ← Ждем завершения хотя бы одной задачи
}
} import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
// exceptionally() - обрабатывает исключение и предоставляет альтернативный результат
CompletableFuture<String> futureWithExceptionHandling =
CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("Что-то пошло не так!");
}
return "Успешный результат";
}).exceptionally(ex -> {
System.out.println("Обработка исключения: " + ex.getMessage());
return "Результат по умолчанию";
});
// handle() - обрабатывает и результат, и исключение
CompletableFuture<String> futureWithHandle = CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("Что-то пошло не так!");
}
return "Успешный результат";
}).handle((result, ex) -> {
if (ex != null) {
System.out.println("Обработка исключения в handle: " + ex.getMessage());
return "Результат по умолчанию";
}
return result.toUpperCase();
});
// whenComplete() - выполняет действие после завершения, но не изменяет результат
CompletableFuture<String> futureWithWhenComplete = CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("Что-то пошло не так!");
}
return "Успешный результат";
}).whenComplete((result, ex) -> {
if (ex != null) {
System.out.println("Исключение в whenComplete: " + ex.getMessage());
} else {
System.out.println("Результат в whenComplete: " + result);
}
});
// Вывод результатов
try {
System.out.println("Результат с exceptionally: " + futureWithExceptionHandling.get());
System.out.println("Результат с handle: " + futureWithHandle.get());
System.out.println("Результат с whenComplete: " + futureWithWhenComplete.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
} mport java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DataLoadingExample {
// Имитация загрузки данных из разных источников
public static String loadUserData(String userId) {
try {
Thread.sleep(1000); // Имитация задержки сети
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Данные пользователя " + userId;
}
public static String loadUserOrders(String userId) {
try {
Thread.sleep(1500); // Имитация задержки сети
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Заказы пользователя " + userId;
}
public static String loadUserRecommendations(String userId) {
try {
Thread.sleep(800); // Имитация задержки сети
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Рекомендации для пользователя " + userId;
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
String userId = "user123";
// Асинхронная загрузка данных из разных источников
CompletableFuture<String> userDataFuture = CompletableFuture.supplyAsync(
() -> loadUserData(userId), executor);
CompletableFuture<String> userOrdersFuture = CompletableFuture.supplyAsync(
() -> loadUserOrders(userId), executor);
CompletableFuture<String> userRecommendationsFuture = CompletableFuture.supplyAsync(
() -> loadUserRecommendations(userId), executor);
// Комбинирование результатов
CompletableFuture<String> combinedFuture = userDataFuture
.thenCombine(userOrdersFuture, (userData, userOrders) -> {
return userData + "\\n" + userOrders;
})
.thenCombine(userRecommendationsFuture, (combinedData, recommendations) -> {
return combinedData + "\\n" + recommendations;
});
// Обработка исключений
CompletableFuture<String> resultFuture = combinedFuture
.exceptionally(ex -> {
System.err.println("Ошибка при загрузке данных: " + ex.getMessage());
return "Не удалось загрузить данные пользователя";
});
// Обработка результата
resultFuture.thenAccept(result -> {
System.out.println("Загруженные данные:\\n" + result);
});
// Ждем завершения всех операций
try {
resultFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown(); // ← Важно закрыть ExecutorService
}
}
}
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class CompletableFutureTimeout {
public static void main(String[] args) {
// Задача, которая выполняется дольше указанного тайм-аута
CompletableFuture<String> future =
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000); // Имитация долгой операции
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Результат долгой операции";
});
try {
// Устанавливаем тайм-аут в 1 секунду
String result = future.get(1, TimeUnit.SECONDS); // ← Этот вызов вызовет TimeoutException
System.out.println("Результат: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Операция не завершилась в указанное время!");
// Альтернативный подход с orTimeout (Java 9+)
CompletableFuture<String> futureWithTimeout = future
.orTimeout(1, TimeUnit.SECONDS) // ← Устанавливаем тайм-аут
.exceptionally(ex -> {
if (ex instanceof java.util.concurrent.TimeoutException) {
return "Операция превысила тайм-аут";
}
return "Ошибка: " + ex.getMessage();
});
try {
System.out.println("Результат с orTimeout: " + futureWithTimeout.get());
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}
} import java.util.concurrent.*;
public class CompletableFutureCustomExecutor {
public static void main(String[] args)
throws ExecutionException, InterruptedException {
// Создаем кастомный ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(4);
// Используем кастомный Executor
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("Задача 1 выполняется в потоке: " + Thread.currentThread().getName());
return "Результат задачи 1";
}, executor);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("Задача 2 выполняется в потоке: " + Thread.currentThread().getName());
return "Результат задачи 2";
}, executor);
// Комбинируем результаты
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {
System.out.println("Комбинирование выполняется в потоке: " + Thread.currentThread().getName());
return result1 + " + " + result2;
});
// Выводим результат
System.out.println("Результат: " + combinedFuture.get());
// Не забываем закрыть ExecutorService
executor.shutdown();
}
} import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
public class AsyncRestClient {
private final ExecutorService executor;
public AsyncRestClient() {
// Создаем пул потоков для выполнения HTTP-запросов
this.executor = Executors.newFixedThreadPool(10);
}
// Асинхронный HTTP GET-запрос
public CompletableFuture<String> get(String url) {
return CompletableFuture.supplyAsync(() -> {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()))) {
return reader.lines().collect(Collectors.joining());
}
} else {
throw new RuntimeException("HTTP error code: " + responseCode);
}
} catch (IOException e) {
throw new RuntimeException("Error making HTTP request", e);
}
}, executor);
}
// Асинхронный HTTP GET-запрос с тайм-аутом
public CompletableFuture<String> getWithTimeout(String url, long timeout, TimeUnit unit) {
return get(url).orTimeout(timeout, unit);
}
// Закрытие клиента
public void close() {
executor.shutdown();
}
public static void main(String[] args) {
AsyncRestClient client = new AsyncRestClient();
// Пример использования
String apiUrl = "<https://jsonplaceholder.typicode.com/posts/1>";
// Асинхронный запрос
CompletableFuture<String> future = client.get(apiUrl);
// Обработка результата
future.thenAccept(response -> {
System.out.println("Ответ от сервера:");
System.out.println(response);
}).exceptionally(ex -> {
System.err.println("Ошибка при выполнении запроса: " + ex.getMessage());
return null;
});
// Запрос с тайм-аутом
CompletableFuture<String> futureWithTimeout = client.getWithTimeout(apiUrl, 5, TimeUnit.SECONDS);
try {
// Ждем завершения запроса
String response = futureWithTimeout.get();
System.out.println("Ответ от сервера (с тайм-аутом):");
System.out.println(response.substring(0, Math.min(100, response.length())) + "...");
} catch (Exception e) {
System.err.println("Ошибка: " + e.getMessage());
} finally {
client.close(); // ← Важно закрыть клиент
}
}
}