乐趣区

关于java:CallableFuture和FutureTask

Callable 接口

 public interface Callable<V> {V call() throws Exception;
}
  • java1.1 推出了 Runnable,而 Callable 是在 java1.5 被引入
  • 与 Runnable 类似,有且仅有一个办法,在 java 8 时被申明为函数式接口
  • 为了解决 Runnable 不能从执行中返回后果的问题,产生了 Callable,相当于在原有性能上削减了后果返回、勾销、异样抛出的性能。
  • 运行一个 Callable 线程有三种形式,你会失去的对象有两种类型,它们是 Future 和 FutureTask

Future 接口

 interface Future<V> {
// 取得线程的执行后果
    V get();
// 定义了期待在以后线程中期待后果的最大工夫
    V get(long timeout, TimeUnit unit);
// 勾销工作,标记 mayInterrupt 示意如果工作曾经开始并且此刻正在运行,那么应该被中断。boolean cancel(boolean mayInterruptIfRunning);
// 查看一个工作是否曾经被实现
    boolean isCancelled();
// 查看工作是否被勾销
    boolean isDone();}
  • Future 能够被看作一个整顿存储 Callable 计算结果的容器。callable 的计算能继续在另一个线程中,并且任何获取一个 Future 后果的尝试都将被阻塞,并且一旦(后果)变得可用,便会返回后果。

Future 提供了查看计算是否实现的办法,以期待计算的实现,并获取计算的后果。计算实现后只能应用 get 办法来获取后果,如果线程没有执行完,Future.get() 办法可能会阻塞以后线程的执行;如果线程出现异常,Future.get() 会 throws InterruptedException 或者 ExecutionException;如果线程曾经勾销,会跑出 CancellationException。勾销由 cancel 办法来执行。isDone 确定工作是失常实现还是被勾销了。一旦计算实现,就不能再勾销计算。如果为了可勾销性而应用 Future 但又不提供可用的后果,则能够申明 Future<?> 模式类型,并返回 null 作为底层工作的后果。

  • 应用线程池的 commit 办法运行一个 Callable 线程,就能够失去一个 Future 对象:
    ExecutorService es = Executors.newSingleThreadExecutor();
    Callable<String> task = () -> {return "123"};
    Future<String> result = es.submit(task);

FutureTask

  • FutureTask 实现了 RunnableFuture 接口,而 RunnableFuture 同时继承了 Runnable 和 Future 两个接口
  • FutureTask 是 Future 接口的一个惟一实现类。
  • FutureTask 提供了 2 个结构器:
public FutureTask(Callable<V> callable) {}
public FutureTask(Runnable runnable, V result) {}
  • 如果只是运行一个简略的 Callable 线程,不想配置线程池,可应用 Callable 结构一个 FutureTask 对象,并放入 Thread 中进行 start()
  • 当然,也能够应用线程池对一个 FutureTask 对象进行 submit() 操作
// 第一种形式
ExecutorService executor = Executors.newCachedThreadPool();
Callable<String> task = () -> {return "123"};
FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
executor.submit(futureTask);
executor.shutdown();
     
// 第二种形式,留神这种形式和第一种形式成果是相似的,只不过一个应用的是 ExecutorService,一个应用的是 Thread
Callable<String> task = () -> {return "123"};
FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
Thread thread = new Thread(futureTask);
thread.start();

总结

如果你有很多工作要去执行,并且所有的工作并不依赖前一个的执行后果,如果你的计算机容许,你能够应用多线程应用多个处理器同时解决所有的工作。这可能使你的程序执行的更快。

退出移动版