并发编程 Future

本文将介绍并发编程中的 Future 及线程执行结果的获取方式

一、Runnable 和 Callable

具体请看:

并发编程 Runnable 和 Callable

二、Future

Future 是一个接口,代表异步操作的结果。

它提供了以下方法:

  • boolean cancel(boolean mayInterruptIfRunning):取消操作的执行

    mayInterruptIfRunning 为 true 时,即使任务已经开始,也会将其强行中断

  • boolean isCancelled():返回操作是否被取消

  • boolean isDone():返回操作是否结束

    执行完成、执行异常、执行取消,都会返回 true

  • V get():获取操作结果,阻塞等待

  • V get(long timeout, TimeUnit unit):获取操作结果,阻塞等待,直至超时

三、FutureTask

FutureTask 是一个类,实现了 Runnable, Future 接口,该类代表可以执行且可以获取结果的异步操作。

FutureTask 提供了两个构造函数:

1
2
3
4
5
6
7
8
9
10
11
public FutureTask(Callable<V> callable) {
···
this.callable = callable;
···
}

public FutureTask(Runnable runnable, V result) {
···
this.callable = Executors.callable(runnable, result);
···
}

简单来说,FutureTask 可以接收 CallableRunnable + 结果对象,并将它们都以 Callable 的形式放置于类中。

FutureTask 实现了 Runnable 接口,因此它可以作为任务被交给 ThreadPoolExecutor。

FutureTask 实现了 Future 接口,因此它也可以用于查看运行状态、获取异步结果。

当 FutureTask 的 run() 方法被执行时,它会自己在内部维护执行状态及执行结果,这些信息会通过 Future 接口的方法向外暴露。因此,FutureTask 可以 作为任务被运行 并且可以 查看自己的运行状态和运行结果

使用示例:

1
2
3
4
FutureTask<Integer> futureTask = new FutureTask<>(()-> 1+2);
ExecutorService es = Executors.newCachedThreadPool();
es.submit(futureTask);
Integer result = futureTask.get();

四、结果获取

1. 线程池的执行结果获取

具体请看:

并发编程 线程池 - 三、任务执行与结果获取

2. Thread 的执行结果获取

可以借助 FutureTask 实现,具体如下:

1
2
3
4
5
6
7
8
9
FutureTask<?> futureTask = new FutureTask<>(()-> {
···
return ···;
});

Thread thread = new Thread(futureTask);
thread.start();

futureTask.get();

参考

  • Java 并发编程实战