在 Java 中,异步编程是指在执行某个操作时,不会阻塞主线程,允许程序继续执行其他任务,直到操作完成后再处理结果。Java 提供了多种方法来实现异步编程,包括使用 Thread
类、ExecutorService
接口、CompletableFuture
类等。
1. 使用 Thread
类
最基本的方式是直接创建一个新的线程来执行任务。这种方式是手动管理线程的方式,比较简单,但在复杂的场景中可能导致资源浪费和线程管理困难。
public class ThreadExample {
public static void main(String[] args) {
// 创建新线程
Thread thread = new Thread(() -> {
// 异步执行任务
try {
Thread.sleep(2000); // 模拟长时间任务
System.out.println("Task completed in thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start(); // 启动线程
// 主线程继续执行
System.out.println("Main thread is not blocked");
}
}
2. 使用 ExecutorService
ExecutorService
是一个更高级的线程池框架,用于管理和调度任务,它可以自动管理线程池中的线程,避免了手动创建和管理线程的麻烦。
使用 ExecutorService
执行异步任务:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 提交异步任务
executorService.submit(() -> {
try {
Thread.sleep(2000); // 模拟长时间任务
System.out.println("Task completed in thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 主线程继续执行
System.out.println("Main thread is not blocked");
// 关闭线程池
executorService.shutdown();
}
}
3. 使用 CompletableFuture
CompletableFuture
是 Java 8 引入的一个强大的异步编程工具,它提供了更丰富的 API 来处理异步任务,支持链式调用、合并任务、处理异常等。
基本的 CompletableFuture
异步示例
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
// 异步执行任务
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(2000); // 模拟长时间任务
System.out.println("Task completed in async");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 主线程继续执行
System.out.println("Main thread is not blocked");
// 等待异步任务完成
future.join(); // 阻塞直到异步任务完成
}
}
使用 CompletableFuture
获取结果
import java.util.concurrent.CompletableFuture;
public class CompletableFutureResultExample {
public static void main(String[] args) {
// 异步计算结果
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000); // 模拟长时间任务
return 42;
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
});
// 主线程继续执行
System.out.println("Main thread is not blocked");
// 获取异步任务的结果
future.thenAccept(result -> {
System.out.println("The result is: " + result);
});
// 等待异步任务完成
future.join(); // 阻塞直到异步任务完成
}
}
链式调用
CompletableFuture
提供了链式调用的方式,可以在前一个任务完成后继续执行后续任务。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureChainingExample {
public static void main(String[] args) {
// 异步任务链式调用
CompletableFuture.supplyAsync(() -> {
return 2; // 初始值
})
.thenApplyAsync(result -> {
return result * 2; // 第一个处理任务:乘以2
})
.thenApplyAsync(result -> {
return result + 3; // 第二个处理任务:加3
})
.thenAccept(result -> {
System.out.println("Final result: " + result); // 输出最终结果
});
// 主线程继续执行
System.out.println("Main thread is not blocked");
// 主线程阻塞,等待异步任务完成
try {
Thread.sleep(3000); // 等待任务完成
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
4. 异常处理
CompletableFuture
还支持对异步任务的异常进行处理,使用 exceptionally
或 handle
方法来捕获并处理异常。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExceptionHandlingExample {
public static void main(String[] args) {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
if (true) { // 模拟异常
throw new RuntimeException("Something went wrong");
}
return 42;
});
future.exceptionally(ex -> {
System.out.println("Exception occurred: " + ex.getMessage());
return 0; // 异常处理后返回默认值
});
// 主线程阻塞,等待任务完成
future.join();
}
}
总结
Thread
:基础的异步执行方式,手动管理线程,适用于简单的异步操作。ExecutorService
:线程池框架,自动管理线程,适合执行多个并发任务。CompletableFuture
:高级异步编程工具,支持任务链式调用、异常处理、合并多个异步任务,适用于复杂的异步操作。
CompletableFuture
是推荐的异步编程方式,因为它提供了强大的功能、流式API和对异步操作的更好控制。