前言
Future
是 Java 中用于表示异步计算结果的接口,它允许你在一个线程中开启一个任务,然后在另一个线程中获取计算结果。Future
接口提供了一种在任务执行完成之后获取结果的机制,它允许异步地等待任务完成。
以下是关于 Future
的详细讲解:
1. Future
接口
Future
接口定义了与异步计算结果相关的一系列方法,其中最重要的是:
get()
: 获取计算结果,如果计算尚未完成,则阻塞直到计算完成。get(long timeout, TimeUnit unit)
: 获取计算结果,但是最多等待指定的时间。isDone()
: 判断计算是否完成。cancel(boolean mayInterruptIfRunning)
: 尝试取消任务的执行。
2. FutureTask
类
FutureTask
是 Future
接口的一个实现,同时也是 Runnable
接口的实现。你可以把 FutureTask
提交给 Executor
来执行,并在需要的时候通过 Future
来获取计算结果。
import java.util.concurrent.*; public class FutureTaskExample { public static void main(String[] args) throws InterruptedException, ExecutionException { Callable<Integer> callable = () -> { // 模拟一个耗时的任务 Thread.sleep(2000); return 42; }; FutureTask<Integer> futureTask = new FutureTask<>(callable); // 创建并启动线程 new Thread(futureTask).start(); // 在主线程中继续执行其他任务 System.out.println("Do something else while waiting for the result..."); // 获取计算结果,会阻塞直到任务完成 Integer result = futureTask.get(); // 打印计算结果 System.out.println("Result: " + result); } }
3. ExecutorService
和 submit()
方法
更常见的做法是使用 ExecutorService
来执行 Callable
或 Runnable
,并返回一个 Future
对象。
import java.util.concurrent.*; public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { Callable<Integer> callable = () -> { // 模拟一个耗时的任务 Thread.sleep(2000); return 42; }; ExecutorService executorService = Executors.newSingleThreadExecutor(); // 提交任务并获取 Future 对象 Future<Integer> future = executorService.submit(callable); // 在主线程中继续执行其他任务 System.out.println("Do something else while waiting for the result..."); // 获取计算结果,会阻塞直到任务完成 Integer result = future.get(); // 打印计算结果 System.out.println("Result: " + result); // 关闭线程池 executorService.shutdown(); } }
4. 异常处理
在使用 Future
的时候,需要注意任务可能会抛出异常。你可以使用 try-catch
块来捕获异常。
try { Integer result = future.get(); System.out.println("Result: " + result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
5. 超时处理
如果你不想一直等待任务完成,可以使用带有超时参数的 get
方法。
try { Integer result = future.get(1, TimeUnit.SECONDS); System.out.println("Result: " + result); } catch (InterruptedException | ExecutionException | TimeoutException e) { e.printStackTrace(); }
这样,如果任务在指定时间内没有完成,将抛出 TimeoutException
。
Future
是在 Java 5 中引入的,它为异步编程提供了一种相对简单的方式。然而,随着时间的推移,Java 的并发编程模型已经进一步发展,现在也有其他更高级的并发工具,例如 CompletableFuture。如果你在新的项目中使用异步编程,可能会考虑使用这些更先进的工具。