跳到主要内容

Java Future

Future 是什么

Q: Future 是什么版本后才有的? A: Future 是 Java 5 中引入的,它表示一个异步计算的结果,可以通过 Future 接口来获取计算结果。

Java 的 Future 是一种用于处理异步任务的模式,它允许可以让程序员把耗时的任务从主线程中解耦,从而提高程序的响应能力和吞吐量。

通常来说,Future 可以被用于以下几种情况:

  • 处理异步网络请求:当一个网络请求发出时,Future 可以把它放到另一台机器上运行,而不用等待它完成,然后再去处理其它的任务
  • 实现多线程:Future 可以把一个任务分解成多个任务,并将它们放到多个线程上运行,从而提高程序的执行效率
  • 处理复杂的任务:当一个任务非常复杂时,可以使用 Future 把它分解成更小的任务,并将它们放到多台机器上运行,从而提高程序的执行效率
  • 处理大型数据集:当处理大型数据集时,可以使用 Future 把它分解成更小的任务,并将它们放到多台机器上运行,从而提高程序的执行效率

如何使用 Future

Future 是一个接口,不能直接使用,必须要有一个实现了 Future 接口的类(如:FutureTask)才能使用。FutureTask 是一个实现了 Future 接口的类,它实现了 Runnable 接口,可以把它当作一个任务并将其放到线程池中执行。

示例:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> futureTask = new FutureTask<>(() -> {
int result = 0;
for (int i = 0; i < 100; i++) {
result += i;
}
return result;
});
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("计算结果为:" + futureTask.get()); // 计算结果为:4950
}
}

Future 常用方法

FutureTask 接口提供了一组方法来操作异步任务:

  • boolean cancel(boolean mayInterruptIfRunning) 用于取消任务
  • V get() 用于获取任务的结果
  • boolean isCancelled() 检查任务是否已经被取消
  • boolean isDone() 检查任务是否已经完成
  • void run() 启动任务
  • boolean isDone() 判断任务是否完成

示例:

import java.util.concurrent.*;

/**
* 在这段代码中,会先新建一个FutureTask任务,
* 然后将其交给一个新的线程去执行,
* 当线程开始执行任务时,会先检查该任务是否被取消,
* 如果没有被取消,则在任务执行完成后,调用futureTask的get方法就可以获取任务的执行结果
*/
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {

FutureTask futureTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
System.out.println("this is start");
Thread.sleep(1000);
System.out.println("this is end");
return "idea";
}
});
Thread thread = new Thread(futureTask);
thread.start();
if(futureTask.isCancelled()) {
System.out.println("任务被中断了");
}
Thread.sleep(2000);
if(futureTask.isDone()) {
String result = (String) futureTask.get();
System.out.println(result);
}
}
}

在使用 FutureTask 的时候需要注意些什么?

  • 当使用 FutureTask 时,应该注意检查任务是否已经取消,如果取消就不要继续执行任务。如果 FutureTask 已经取消,应该尽快抛出 CancellationException 异常,来提示程序
  • 使用 FutureTask.get() 方法的时候要注意,因为它会阻塞调用线程,会影响程序性能