在kotlin暂停函数中包装java 7期货的最佳方法是什么?有没有办法将返回Java 7期货的方法转换为挂起函数?
对于任意回调或java 8 completablefutures,该过程非常简单,如下所示:* https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#suspending-functions
在这些情况下,有一个钩子在未来完成时被触发,因此一旦未来的值准备好(或触发异常),它就可以用来恢复延续 .
但是,Java 7期货不公开计算结束时调用的方法 .
将Java 7未来转换为Java 8可完成的未来不是我的代码库中的一个选项 .
当然,我可以创建一个调用future.get()的挂起函数,但这会阻塞,这打破了使用协程暂停的总体目的 .
另一种选择是将runnable提交给新的线程 Actuator ,并在runnable调用future.get()内部并调用回调 . 从消费者的角度来看,这个包装器会使代码看起来像“非阻塞”,协程可以暂停,但是我们仍在编写阻塞代码,我们正在创建一个新的线程,只是为了阻止它
2 回答
Java 7的未来正在受阻 . 它不是为异步API设计的,也没有提供任何方法来安装将来完成时调用的回调 . 这意味着没有直接使用
suspendCoroutine
的方法,因为suspendCoroutine
设计用于使用异步回调的API .但是,如果您的代码实际上是在JDK 8或更新版本下运行,那么您的代码中实际的
Future
实例很可能会在运行时实现CompletionStage
接口 . 您可以尝试将其强制转换为CompletionStage
,并使用kotlinx.coroutines
库的kotlinx-coroutines-jdk8
模块中的即用型CompletionStage.await扩展名 .当然Roman是正确的,Java
Future
不允许您在工作完成时提供回调 .但是,它确实为您提供了检查工作是否完成的方法,如果是,则调用
.get()
将不会阻止 .幸运的是,对于我们来说,我们还有一种廉价的方法来转移线程,以便通过协同程序快速进行民意调查 .
让我们编写轮询逻辑并将其作为扩展方法出售:
然后使用:
因此,我们对Futures完成的毫秒响应时间没有使用任何额外的线程 .
当然,你会想要添加一些上限用作超时,这样你就不会永远等待 . 在这种情况下,我们可以稍微更新一下代码: