Java Future
に変換したいScala Future
オブジェクトがあります。
j.u.c.Future
APIを見ると、isDone
メソッド以外に使用できるものはほとんどありません。このisDone
メソッドはブロックされていますか?
現在、これは私が心に抱いていることです:
val p = Promise()
if (javaFuture.isDone())
p.success(javaFuture.get)
これを行うためのより良い方法はありますか?
それをラップするのはどうですか(ここに暗黙のExecutionContextがあると仮定しています):
val scalaFuture = Future {
javaFuture.get
}
編集:
単純なポーリング戦略は次のようになります(Java.util.Future => F):
def pollForResult[T](f: F[T]): Future[T] = Future {
Thread.sleep(500)
f
}.flatMap(f => if (f.isDone) Future { f.get } else pollForResult(f))
これにより、Java futureが500msごとに実行されるかどうかがチェックされます。明らかに合計ブロッキング時間は上記と同じです(最も近い500msに切り上げられます)が、このソリューションでは他のタスクをインターリーブできます。 ExecutionContext
の同じスレッド。
開始Scala 2.13
、標準ライブラリには scala.jdk.FutureConverters
これはJavaからScala CompletableFuture/Future
暗黙の変換:
import scala.jdk.FutureConverters._
// val javaFuture = Java.util.concurrent.CompletableFuture.completedFuture(12)
val scalaFuture = javaFuture.asScala
// scalaFuture: scala.concurrent.Future[Int] = Future(Success(12))
Java FutureからScala Futureへの変換には、FutureConvertors(Scalaの組み込みutil)を使用します。
Java Future [Int]をScala Future [Int] ::に変換する例を考えてみましょう。
import Java.util.concurrent.CompletableFuture
import scala.compat.Java8.FutureConverters
val javaFuture: Java.util.concurrent.Future[Int] = ???
// Some method call which returns Java's Future[Int]
val scalaFuture: Future[Int] =
FutureConverters.toScala(CompletableFuture.supplyAsync(new Supplier[Int] {
override def get(): Int = javaFuture.get
}))
同様に、Intの代わりに任意のカスタムタイプに対して実行できます。
今この質問を読んでいる人のために、Scala 2.13以降を使用している場合は、以下を使用してください。
_import scala.jdk.FutureConverters._
_
そして、_completableFuture.asScala
_を使用して変換します
Scala 2.12以下を使用している場合は、
_import scala.compat.Java8.FutureConverters
_
そして、次を使用して変換します:toScala(completableFuture)
または_completableFuture.toScala
_
また、Scala 2.12で、正しいアーティファクトを使用していることを確認してください。
_org.scala-lang.modules:scala-Java8-compat_2.12:0.9.0
_
さて、何らかの理由であなたが持っているものが実際にはFuture
ではなくCompletableFuture
である場合、これは最近ではまれなケースですが、これらの答えの最初の1つに従ってください: Transform Java Future into a CompletableFuture