共计 1107 个字符,预计需要花费 3 分钟才能阅读完成。
在执行多个任务的时候,使用 Java 标准库提供的线程池是非常方便的。我们提交的任务只需要实现 Runnable
接口,就可以让线程池去执行:
class Task implements Runnable {public String result;
public void run() {this.result = longTimeCalculation();}
}
Runnable
接口有个问题,它的方法没有返回值。如果任务需要一个返回结果,那么只能保存到变量,还要提供额外的方法读取,非常不便。所以,Java 标准库还提供了一个 Callable
接口,和 Runnable
接口比,它多了一个返回值:
class Task implements Callable<String> {public String call() throws Exception {return longTimeCalculation();}
}
并且 Callable
接口是一个泛型接口,可以返回指定类型的结果。
现在的问题是,如何获得异步执行的结果?
如果仔细看 ExecutorService.submit()
方法,可以看到,它返回了一个 Future
类型,一个 Future
类型的实例代表一个未来能获取结果的对象:
ExecutorService executor = Executors.newFixedThreadPool(4);
// 定义任务:
Callable<String> task = new Task();
// 提交任务并获得 Future:
Future<String> future = executor.submit(task);
// 从 Future 获取异步执行返回的结果:
String result = future.get(); // 可能阻塞
当我们提交一个 Callable
任务后,我们会同时获得一个 Future
对象,然后,我们在主线程某个时刻调用 Future
对象的 get()
方法,就可以获得异步执行的结果。在调用 get()
时,如果异步任务已经完成,我们就直接获得结果。如果异步任务还没有完成,那么 get()
会阻塞,直到任务完成后才返回结果。
一个 Future<V>
接口表示一个未来可能会返回的结果,它定义的方法有:
get()
:获取结果(可能会等待)get(long timeout, TimeUnit unit)
:获取结果,但只等待指定的时间;cancel(boolean mayInterruptIfRunning)
:取消当前任务;isDone()
:判断任务是否已完成。
练习
使用 Future 获取异步执行结果。
下载练习
小结
对线程池提交一个 Callable
任务,可以获得一个 Future
对象;
可以用 Future
在将来某个时刻获取结果。
正文完
星哥玩云-微信公众号