Java 异步编程简介
现代应用程序需要高性能和响应能力。Java 中的异步编程是一种方法,允许执行长时间运行的操作(例如数据库查询、API 调用、文件读取)而不阻塞主执行线程。程序不会等待任务完成,而是继续运行,并在结果准备好时进行处理。
在本指南中,我们将介绍 Java 中异步编程的基本概念,从基础工具开始,一直到现代 API CompletableFuture。您将学习如何创建非阻塞代码、处理错误以及组合异步任务。
基本概念:线程和 ExecutorService
线程 (Threads)
在 Java 中异步执行代码的最简单方法是创建一个新线程。然而,手动创建线程是一项昂贵的操作,并且当任务数量很大时,可能会导致性能问题。
// 创建线程的示例Thread thread = new Thread(() -> { System.out.println("异步任务在线程中执行: " + Thread.currentThread().getName());});thread.start();System.out.println("主线程继续工作");ExecutorService — 线程池管理
为了有效管理线程,Java 提供了 ExecutorService。这是一个接口,允许创建线程池、重用它们并控制任务的执行。
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;
public class ExecutorServiceExample { public static void main(String[] args) { // 创建一个包含4个线程的线程池 ExecutorService executor = Executors.newFixedThreadPool(4); // 提交任务执行 executor.submit(() -> { System.out.println("任务在线程池中执行"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务完成"); }); // 关闭线程池 executor.shutdown(); }}线程池的主要类型:
newFixedThreadPool(n)— 固定数量的线程。newCachedThreadPool()— 动态数量的线程。newSingleThreadExecutor()— 单个线程用于顺序执行任务。newScheduledThreadPool(n)— 用于调度延迟任务。
Future 和 CompletableFuture
Future 接口
Future 是一个接口,表示异步操作的结果。它允许检查任务是否完成、等待任务完成并获取结果。
import java.util.concurrent.*;
public class FutureExample { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Integer> future = executor.submit(() -> { Thread.sleep(2000); return 42; }); System.out.println("等待结果..."); Integer result = future.get(); // 阻塞线程直到获取结果 System.out.println("结果: " + result); executor.shutdown(); }}Future 的缺点是 get() 方法会阻塞线程。为了更灵活地处理异步任务,创建了 CompletableFuture。
CompletableFuture — 强大的异步工具
CompletableFuture<