本文内容如有错误、不足之处欢迎技术爱好者们一同探讨在本文下面讨论区留言感谢。
文章目录
- 简介
- 使用
- 原理
- 总结
- 参考资料
简介
在 Java 中为了编程异步事件我们使用 Thread 类和 Runnable 接口它们可以开发并行应用程序。问题是在执行结束时不能返回值。因此添加了 FutureTaksFuture 和 Callable 类它们与以前的类具有大致相同的功能但极大地促进了并行应用程序的开发。由于线程 Thread 只支持 Runnable 构造于是有了 Future 可以根据 Callable 构建线程。由于 Future 只是一个接口无法直接创建对象因此有了 FutureTask 。 请参阅
- Future封装并行调用的类可以取消任务的执行确定执行是否已成功完成或出错以及其他操作
- FutureTask这是 Future 接口的实现将在并行调用中执行。
- Callable用于实现并行执行的接口。它与 Runnable 接口非常相似但是它不返回任何值而 Callable 必须在执行结束时返回一个值。
- ExecutorService用于在创建线程池开始和取消管理并行执行的线程。
创建线程的3中方式 Thread、Runnable、Callable 其中 Callable 是有返回结果的这种特殊性在某种情况下非常有帮助例如需要知道每个线程计算金额的多少那么需要返回结果并进行保存。
使用
概念
构造方法只有两个
// Creates a FutureTask that will, upon running, execute the given Callable.// 创建一个FutureTask将在运行时执行给定的Callable。FutureTask(Callable callable)// Creates a FutureTask that will, upon running, execute the given Runnable, and arrange that get will return the given result on successful completion.// 创建一个FutureTask将在运行时执行给定的Runnable并在获得成功完成后返回给定结果result。FutureTask(Runnable runnable, V result)
package test;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.logging.Level;import java.util.logging.Logger;/*** Java 项目如何使用FutureTask例子*/public class FutureDemo {private static final ExecutorService threadpool Executors.newFixedThreadPool(3);public static void main(String args[]) throws InterruptedException, ExecutionException {FactorialCalculator task new FactorialCalculator(10);System.out.println("Submitting Task ...");Future future threadpool.submit(task);System.out.println("Task is submitted");while (!future.isDone()) {System.out.println("Task is not completed yet....");Thread.sleep(1); //睡眠1秒}System.out.println("Task is completed, lets check result");long factorial future.get();System.out.println("Factorial of 1000000 is : " factorial);threadpool.shutdown();}private static class FactorialCalculator implements Callable {private final int number;public FactorialCalculator(int number) {this.number number;}Overridepublic Long call() {long output 0;try {output factorial(number);} catch (InterruptedException ex) {Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);}return output;}private long factorial(int number) throws InterruptedException {if (number 0) {Thread.sleep(1); // 等待1秒时间模拟计算result result * number;number--;}return result;}}}
输出结果
Submitting Task ...Task is submittedTask is not completed yet....Task is not completed yet....Task is not completed yet....Task is completed, lets check resultFactorial of 1000000 is : 3628800
原理
原理是将 Runnable 转换为 Callable 。
public static Callable callable(Runnable task, T result) {if (task null)throw new NullPointerException();return new RunnableAdapter(task, result);}
采用适配器模式调用 RunnableAdapter(task, result) 方法来适配
static final class RunnableAdapter implements Callable {final Runnable task;final T result;RunnableAdapter(Runnable task, T result) {this.task task;this.result result;}public T call() {task.run();return result;}}
通过 Callable 的 call() 调用 Runnable 的 run()把传入的 T result 作为 Callable 的返回结果
总结
通过使用 FutureTask 类以及 Callable 和 Futere 接口异步 Java 任务的编程变得更加容易避免了实现此类应用程序以前所需的“麻烦”。
参考资料
How to use Future and FutureTask in Java Concurrency with Example如何通过示例在Java并发中使用Future和FutureTask
- https://javarevisited.blogspot.com/2015/01/how-to-use-future-and-futuretask-in-Java.html
Java FutureTask Example Program Java FutureTask示例程序
- https://www.journaldev.com/1650/java-futuretask-example-program
Class FutureTaskFutureTask类
- https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html
what is the advantage of using FutureTask over Callable?与Callable相比使用FutureTask有什么优势
- https://stackoverflow.com/questions/30976946/what-is-the-advantage-of-using-futuretask-over-callable
Processamento assíncrono em Java com Future e FutureTask带有Future和FutureTask的异步Java处理
- https://www.devmedia.com.br/processamento-assincrono-em-java-com-future-e-futuretask/33851