🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # Runnable、Callable、Future 和 FutureTask ## 定义 ```java public interface Runnable { public abstract void run(); } public interface Callable<V> { V call() throws Exception; } public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; } public class FutureTask<V> implements RunnableFuture<V> { public FutureTask(Callable<V> callable) { ... } public FutureTask(Runnable runnable, V result) { ... } ... } ``` 可以看到: 1、Callable 是一个泛型接口,被线程执行后,可以有返回值;而 Runnable 没有返回值 2、Future 是一个接口,定义了对具体的 Runnable 或 Callable 任务进行的一系列操作,包括:取消、查询是否被取消、查询是否完成、获取结果 3、FutureTask 实现了 RunnableFuture,而 RunnableFuture 又继承自 Runnable 和 Future。所以 FutureTask 既可以作为 Runnable 被线程执行,又可以作为 Future 得到 Callable 的返回值 ## 执行任务 执行线程任务有两种方式,分别为通过 ExecutorService 和 Thread: ```java Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { // do something return 0; } }; ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<Integer> future = executorService.submit(callable); ``` ```java new Thread(new Runnable() { @Override public void run() { // do something } }).start(); ``` 其中 * Executor 可以接收 Callable 形式或 Runnable 形式,传入 Runnable 最终也会转换为 Callable; * Thread 方式只能接收 Runnable 形式。 ## Future 我们可以通过实现 Future 接口的对象,来对执行任务的 Callable 或 Runnable 进行一系列操作。示例如下: ```java ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<Integer> future = executorService.submit(callable); try { Log.i(TAG, "result is " + future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } ``` ## FutureTask FutureTask 弥补了 Thread 只能接收 Runnable 参数,并且不能获取返回值的问题。 1、FutureTask 作为 Runnable ```java Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { // do something return 0; } }; FutureTask<Integer> futureTask = new FutureTask<>(callable); new Thread(futureTask).start(); ``` 2、FutureTask 作为 Future,获取返回值 ```java Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { // do something return 0; } }; FutureTask<Integer> futureTask = new FutureTask<>(callable); new Thread(futureTask).start(); // FutureTask 作为 Future,获取返回值 try { Log.i(TAG, "test: " + futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } ```