芯片|Java:理解Java中的Callable接口和Future接口

芯片|Java:理解Java中的Callable接口和Future接口

在java中 , Runnable 接口仅提供多线程编程的基本功能 。 它有很多限制 。 Callable 和 Future 接口解决了许多限制 。

Runnable接口
Runnable 接口用于指定一个打算由线程执行的类 。 它有一个单独的无参数方法 , 称为 run() , 它必须被实现的类覆盖 。 这个接口的核心思想是为那些想要在代码仍在执行中执行的对象提供一个通用协议——换句话说 , 一个正在运行的代码段调用另一段代码而不被停止或终止(同时执行) 。 有一个名为 Thread 的类 , 它提供相同的功能 , 但不同之处在于它必须是子类(继承)才能使用 。 存在接口和类的原因是为了达到相同的目标 , 这是面向对象设计所遵循的建议:除非我们打算通过操作一个或多个类来改变它的含义 , 否则不应继承类 。 它的方法和增强它的属性 。 通过实现 Thread 类的对应接口 , 称为 Runnable , 我们几乎可以摆脱扩展类(子类化)的重任 , 同时在我们的程序中获得线程实现的全部好处 。 Java API 文档也符合相同的想法:在大多数情况下 , 如果你打算覆盖 run() 方法而不是其他 Thread 方法 , 则应该使用 Runnable 接口 。
请注意 , 多线程编程是一个庞大而复杂的领域 。 Runnable 接口仅提供基本功能 。 当执行长操作并且应用程序希望在执行之间进行通信时 , 这会造成严重的限制 。 因为 run 方法不返回值 , 所以跨执行线程进行通信的唯一方法是使用共享的可变数据 。 现在 , 共享数据的问题是它们必须同步才能在调用线程之间进行读写 。 Callable 接口试图解决这个限制 。

Callable接口
Callable接口旨在定义一个返回结果并可能引发异常的任务 。 它在 java.util.concurrent 包中声明 。 此接口还包含一个单一的、无参数的方法 , 称为 call () , 将被此接口的实现者覆盖 。 该方法与Runnable接口的run()方法类似 , 只是它返回一个值 , 并且可以抛出一个已检查的异常 。 事实上 , 整个想法是 Callable 只不过是 Runnable , 因为这两个接口都指定了一个有可能被另一个线程执行的类 , 只是它不受 Runnable 的限制 。
因此 , Callable 和 Runnable 的使用几乎是可以互换的 , 除了我们谈到的原因 。 使用 Callable 的应用程序通常与实现 Runnable 或 Callable 接口的其他类同时运行 。
Future 接口
Future 接口是一个通用接口 , 表示从异步计算返回的值 。 它包含检查计算是否已完成或等待它 , 检索结果的方法 。 在前面的代码中 , Future 的 get() 方法阻塞了调用线程 , 等待 Callable 完成计算 , 然后检索结果 。 该接口还包含取消 Callable 执行的方法 。 但是 , 一旦计算完成 , 就不能取消 。
在这个接口的众多实现中 , Java 8 引入的 CompletableFuture 类使我们能够异步执行 Runnable 来执行不返回值的任务 , 以及返回值的 Supplier 任务 。 Supplier 是一个函数式接口 , 它包含一个单一的、无参数的方法 , 称为 get() , 并返回一个结果 , 如 Callable 。 CompletableFuture 类具有各种高级功能 , 供程序员对 Future 接口进行操作 。
结论
【芯片|Java:理解Java中的Callable接口和Future接口】Callable 接口是对 Java 并发 API 的一个有趣的补充; 它解决了 Runnable 的问题 。 通过 Callable 创建的线程可以返回一个值 。 这是一个强大的功能 , 可用于创建一个多线程程序 , 该程序可以返回由多个线程同时完成的各种部分或全部完成的计算结果 。 此外 , 线程可以返回它们的状态码 , 指示其计算的成功或不成功的计算 。