Java 执行器:当任务完成时,如何在不阻塞的情况下收到通知

作者:编程家 分类: java 时间:2025-10-21

Java 执行器:当任务完成时,如何在不阻塞的情况下收到通知?

在 Java 编程中,执行器(Executor)是一种用于执行异步任务的框架。它提供了一种方便的方式来管理和调度任务,同时还能够提供通知机制来告知任务的完成情况。当任务完成时,我们通常希望能够在不阻塞的情况下收到通知,以便继续执行其他操作或处理任务的结果。本文将介绍如何在使用 Java 执行器时实现这一目标。

使用 Future 接口

Java 执行器框架中的一个关键组件是 Future 接口。它代表一个异步计算的结果,并提供了一些方法来检查任务是否完成、取消任务以及获取任务的结果。通过使用 Future 接口,我们可以在任务完成后立即获取结果,而不需要阻塞等待任务的完成。

下面是一个使用 Future 接口的示例代码:

java

import java.util.concurrent.*;

public class ExecutorExample {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService executor = Executors.newSingleThreadExecutor();

Future future = executor.submit(() -> {

// 执行一些耗时的操作

Thread.sleep(2000);

return 42;

});

// 检查任务是否完成

while (!future.isDone()) {

System.out.println("任务尚未完成...");

Thread.sleep(500);

}

// 获取任务的结果

int result = future.get();

System.out.println("任务完成,结果为:" + result);

executor.shutdown();

}

}

在上面的示例中,我们使用了 ExecutorService 的 submit 方法来提交一个 Callable 对象作为任务,并返回一个 Future 对象。通过调用 Future 对象的 isDone 方法,我们可以检查任务是否完成。如果任务尚未完成,我们可以继续执行其他操作,而不需要阻塞等待任务的完成。当任务完成后,我们可以通过调用 Future 对象的 get 方法来获取任务的结果。

使用 CompletionService 接口

除了 Future 接口,Java 执行器框架还提供了 CompletionService 接口。它是一个更高级的接口,用于将任务的提交和结果的获取合并在一起。通过使用 CompletionService 接口,我们可以在任务完成时立即获取结果,而不需要手动检查每个任务的完成状态。

下面是一个使用 CompletionService 接口的示例代码:

java

import java.util.concurrent.*;

public class ExecutorExample {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService executor = Executors.newFixedThreadPool(5);

CompletionService completionService = new ExecutorCompletionService<>(executor);

for (int i = 0; i < 10; i++) {

final int taskId = i;

completionService.submit(() -> {

// 执行一些耗时的操作

Thread.sleep(2000);

return taskId;

});

}

for (int i = 0; i < 10; i++) {

Future future = completionService.take();

int result = future.get();

System.out.println("任务 " + result + " 完成");

}

executor.shutdown();

}

}

在上面的示例中,我们使用了 ExecutorService 的 newFixedThreadPool 方法创建了一个固定大小的线程池,并使用 ExecutorCompletionService 对象包装该线程池。通过调用 CompletionService 对象的 submit 方法,我们可以提交任务,并立即获得一个 Future 对象。通过调用 CompletionService 对象的 take 方法,我们可以获取已完成的任务的 Future 对象,从而获取任务的结果。

在使用 Java 执行器时,我们可以通过使用 Future 接口或 CompletionService 接口来实现在任务完成时在不阻塞的情况下收到通知。通过这些接口,我们可以更好地管理和调度异步任务,并及时获取任务的结果。以上是两种常用的实现方式,根据实际需求选择合适的方式来处理任务的完成通知。