Master Java Asynchronous Programming: 7 Powerful Techniques with Code Samples
This article explains why asynchronous programming boosts Java application performance and walks through seven practical methods—Thread, FutureTask, CompletableFuture, Guava ListenableFuture, EA‑Async, Cactoos, and Jcabi‑Aspects—each illustrated with complete, runnable code examples.
Asynchronous programming improves responsiveness and performance by allowing a program to continue executing other tasks while waiting for I/O or long‑running operations.
This article introduces seven ways to implement async programming in Java, each accompanied by concise code examples.
1. Thread
Using the core Thread class or a lambda to run a task in a separate thread.
<code>public class FactorialThread extends Thread {
private int number;
public FactorialThread(int number, String name) {
super(name);
this.number = number;
}
private long factorial(int n) {
long result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
@Override
public void run() {
long result = factorial(number);
System.out.println(Thread.currentThread().getName() + " -> " + number + " 的阶乘是: " + result);
}
public static void main(String[] args) {
Thread t1 = new FactorialThread(5, "T1");
t1.start();
Thread t2 = new FactorialThread(7, "T2");
t2.start();
}
}
</code> <code>T1 -> 5 的阶乘是: 120
T2 -> 7 的阶乘是: 5040
</code>A lambda version can further simplify the code:
<code>Thread t3 = new Thread(() -> {
int num = 8;
int result = 1;
for (int i = 1; i <= num; i++) {
result *= i;
}
System.out.println(Thread.currentThread().getName() + " -> " + num + " 的阶乘是: " + result);
}, "T3");
t3.start();
</code>2. FutureTask
Since Java 5, FutureTask combined with an ExecutorService can run tasks asynchronously and retrieve results.
<code>try (ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10))) {
int num = 8;
Future<Integer> task = executor.submit(() -> {
int result = 1;
for (int i = 1; i <= num; i++) {
result *= i;
}
return result;
});
Integer result = task.get();
System.out.printf("%s -> %s 的阶乘是: %s%n",
Thread.currentThread().getName(), num, result);
executor.shutdown();
}
</code>You can check completion with task.isDone() and handle exceptions that occur inside the task.
3. CompletableFuture
Java 8 introduced CompletableFuture , which merges Future and CompletionStage to provide a rich asynchronous API.
<code>final int num = 10;
CompletableFuture<Long> cf = CompletableFuture.supplyAsync(() -> {
long result = 1;
for (int i = 1; i <= num; i++) {
result *= i;
}
return result;
});
Long result = cf.get();
System.out.printf("%s -> %s 的阶乘是: %s%n",
Thread.currentThread().getName(), num, result);
</code>For fire‑and‑forget tasks, runAsync with join() can be used:
<code>CompletableFuture.runAsync(() -> {
System.out.printf("%s - %s 开始执行任务%n",
Thread.currentThread().getName(), System.currentTimeMillis());
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {}
System.out.printf("%s - %s 任务执行完成%n",
Thread.currentThread().getName(), System.currentTimeMillis());
}).join();
</code>4. Guava ListenableFuture
Guava adds ListenableFuture , which allows registration of callbacks.
<code><dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.4.0-jre</version>
</dependency>
</code> <code>ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 60,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
ListeningExecutorService les = MoreExecutors.listeningDecorator(executor);
int num = 8;
ListenableFuture<Long> future = les.submit(() -> {
long result = 1;
for (int i = 1; i <= num; i++) {
result *= i;
}
return result;
});
System.out.printf("%s -> %s 的阶乘是: %s%n",
Thread.currentThread().getName(), num, future.get());
future.addListener(() -> {
System.err.printf("%s - 计算完成%n", Thread.currentThread().getName());
try {
System.out.printf("%s -> %s 的阶乘是: %s%n",
Thread.currentThread().getName(), num, future.get());
} catch (InterruptedException | ExecutionException e) {}
}, executor);
</code>5. EA‑Async
The ea‑async library enables sequential‑style asynchronous code.
<code><dependency>
<groupId>com.ea.async</groupId>
<artifactId>ea-async</artifactId>
<version>1.2.3</version>
</dependency>
</code> <code>static { Async.init(); }
public static long factorial(long num) {
long result = 1;
for (int i = 1; i <= num; i++) { result *= i; }
return result;
}
public static void main(String[] args) {
final long num = 10;
CompletableFuture<Long> cf = CompletableFuture.supplyAsync(() -> factorial(num));
long result = Async.await(cf);
System.out.printf("%s -> %s 的阶乘是: %s%n",
Thread.currentThread().getName(), num, result);
}
</code>6. Cactoos
Cactoos provides an object‑oriented alternative to traditional utility libraries.
<code><dependency>
<groupId>org.cactoos</groupId>
<artifactId>cactoos</artifactId>
<version>0.56.1</version>
</dependency>
</code> <code>public static long factorial(long num) {
long result = 1;
for (int i = 1; i <= num; i++) { result *= i; }
System.err.println("当前执行线程: " + Thread.currentThread().getName());
return result;
}
public static void main(String[] args) throws Exception {
final long num = 10;
Async<Long, Long> asyncFunction = new Async<>(input -> factorial(input));
Future<Long> asyncFuture = asyncFunction.apply(num);
long result = asyncFuture.get();
System.out.printf("%s -> %s 的阶乘是: %s%n",
Thread.currentThread().getName(), num, result);
}
</code>7. Jcabi‑Aspects
Jcabi‑Aspects offers an @Async annotation powered by AspectJ AOP.
<code><dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-aspects</artifactId>
<version>0.26.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.20.1</version>
</dependency>
</code> <code>@Async
public void task(long num) {
long result = 1;
for (int i = 1; i <= num; i++) { result *= i; }
System.err.printf("%s - 计算结果: %s%n",
Thread.currentThread().getName(), result);
}
public static void main(String[] args) throws Exception {
JcabiAspectTest at = new JcabiAspectTest();
at.task(10L);
System.in.read();
}
</code>Additional annotations such as @Loggable can add logging without extra code.
All examples are compatible with Java 21 and can be run in a Spring Boot 3 project, providing a practical toolbox for modern backend development.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.