package com.example.demo.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@Service
public class AsyncService {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
// Simple async operation
public CompletableFuture<String> fetchUserData(Long userId) {
return CompletableFuture.supplyAsync(() -> {
// Simulate API call
sleep(1000);
return "User data for ID: " + userId;
}, executor);
}
// Chain operations
public CompletableFuture<String> processUserData(Long userId) {
return fetchUserData(userId)
.thenApply(data -> data.toUpperCase())
.thenApply(data -> "Processed: " + data);
}
// Combine multiple futures
public CompletableFuture<String> getUserProfile(Long userId) {
CompletableFuture<String> userFuture = fetchUserData(userId);
CompletableFuture<String> postsFuture = fetchUserPosts(userId);
CompletableFuture<String> friendsFuture = fetchUserFriends(userId);
return userFuture.thenCombine(postsFuture, (user, posts) ->
user + ", " + posts)
.thenCombine(friendsFuture, (combined, friends) ->
combined + ", " + friends);
}
// Sequential composition
public CompletableFuture<String> getRecommendations(Long userId) {
return fetchUserData(userId)
.thenCompose(userData -> {
// Use userData to fetch recommendations
return CompletableFuture.supplyAsync(() -> {
sleep(500);
return "Recommendations based on: " + userData;
}, executor);
});
}
// Exception handling
public CompletableFuture<String> fetchWithFallback(Long userId) {
return fetchUserData(userId)
.exceptionally(ex -> {
System.err.println("Error fetching user: " + ex.getMessage());
return "Default user data";
});
}
// Handle both success and failure
public CompletableFuture<String> fetchWithHandling(Long userId) {
return fetchUserData(userId)
.handle((result, ex) -> {
if (ex != null) {
return "Error: " + ex.getMessage();
}
return result;
});
}
// Wait for all futures
public CompletableFuture<List<String>> fetchMultipleUsers(List<Long> userIds) {
List<CompletableFuture<String>> futures = userIds.stream()
.map(this::fetchUserData)
.collect(Collectors.toList());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
}
// Race multiple operations
public CompletableFuture<String> fetchFromFastestSource(Long userId) {
CompletableFuture<String> db = fetchFromDatabase(userId);
CompletableFuture<String> cache = fetchFromCache(userId);
CompletableFuture<String> api = fetchFromAPI(userId);
return CompletableFuture.anyOf(db, cache, api)
.thenApply(result -> (String) result);
}
// Spring @Async annotation alternative
@Async
public CompletableFuture<String> asyncMethod(Long userId) {
sleep(2000);
return CompletableFuture.completedFuture("Async result for " + userId);
}
// Helper methods
private CompletableFuture<String> fetchUserPosts(Long userId) {
return CompletableFuture.supplyAsync(() -> {
sleep(800);
return "Posts for user " + userId;
}, executor);
}
private CompletableFuture<String> fetchUserFriends(Long userId) {
return CompletableFuture.supplyAsync(() -> {
sleep(600);
return "Friends of user " + userId;
}, executor);
}
private CompletableFuture<String> fetchFromDatabase(Long userId) {
return CompletableFuture.supplyAsync(() -> {
sleep(1500);
return "DB: User " + userId;
}, executor);
}
private CompletableFuture<String> fetchFromCache(Long userId) {
return CompletableFuture.supplyAsync(() -> {
sleep(100);
return "Cache: User " + userId;
}, executor);
}
private CompletableFuture<String> fetchFromAPI(Long userId) {
return CompletableFuture.supplyAsync(() -> {
sleep(2000);
return "API: User " + userId;
}, executor);
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
CompletableFuture enables non-blocking asynchronous programming in Java. I use supplyAsync() to run tasks in thread pools and thenApply() to chain transformations. thenCompose() flattens nested futures, while thenCombine() merges independent futures. Exception handling uses exceptionally() or handle() to recover from failures. allOf() waits for multiple futures, anyOf() completes when any finishes. CompletableFuture integrates with Spring's @Async for method-level parallelism. Callbacks execute on completion without blocking threads. Custom executors control thread pool behavior. The API supports both callback and imperative styles with join() or get(). CompletableFuture improves throughput by freeing threads during I/O operations, essential for scalable microservices.
Related snips
export interface RetryOptions {
retries: number;
baseMs: number;
maxMs: number;
signal?: AbortSignal;
onRetry?: (attempt: number, delay: number, err: unknown) => void;
Exponential backoff with jitter for retries
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: String!
GraphQL API with Spring Boot
use crossbeam::channel::unbounded;
use std::thread;
fn main() {
let (tx, rx) = unbounded();
Crossbeam for advanced concurrent data structures
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
setTimeout(() => {
if (success) {
Promises and async/await patterns for asynchronous JavaScript
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
Channels (mpsc) for message passing between threads
export type Settled<R> =
| { status: 'fulfilled'; value: R }
| { status: 'rejected'; reason: unknown };
export interface ConcurrencyOptions {
limit: number;
Simple concurrency limiter for batch operations
Share this code
Here's the card — post it anywhere.