web-dev-qa-db-ja.com

Java.util.concurrent.Futureのscala.concurrent.Futureラッパー

Play Framework2.1.1を外部のJavaライブラリでJava.util.concurrent.Futureの結果を生成します。scala Play 2.1の時点で行うのが正しいと思うAkkaとは対照的に、futureです。コードをブロックしないままJava.util.concurrent.Futureをscala.concurrent.Futureにラップするにはどうすればよいですか?

def geConnection() : Connection = {
  // blocking with get
  connectionPool.getConnectionAsync().get(30000, TimeUnit.MILLISECONDS)
}

上記のコードは接続を返しますが、getを使用するため、ブロックされます

def getConnectionFuture() : Future[Connection] = {
  future {
    // how to remove blocking get and return a scala future?
    connectionPool.getConnectionAsync().get(30000, TimeUnit.MILLISECONDS)
  }
}

理想的には、上記のコードのように未来として接続を返すが、getを介してコードをブロックしない、scala関数が必要です。ブロックしないようにするには、他に何を関数に入れる必要がありますか? 。

どんなポインタも素晴らしいでしょう。

21
Mark Sivill
import Java.util.concurrent.{Future => JFuture}
import scala.concurrent.{Future => SFuture}

JFutureSFuture でラップすることはできません。 SFutureonComplete)のコールバックであり、getにはブロッキングJFutureのみがあります。

追加のスレッドを作成し、それをgetでブロックしてから、 Promise を完了してgetの結果を取得するだけです。

val jfuture: JFuture[T] = ???
val promise = Promise[T]()
new Thread(new Runnable { def run() { promise.complete(Try{ jfuture.get }) }}).start
val future = promise.future

エンドレスループでisDoneをチェックすることはできますが、ブロックするよりも良いとは思いません。

21
senia
Future {
  blocking {
    jfuture.get
  }
}

これにより、ExecutionContextは、実行していることがブロックされることを認識し、より多くのスレッドを割り当てる機会を与えます。 blocking { }を含めないと、スレッドが不足する可能性があります。

6
Dr.Haribo
     import Java.util.concurrent.{Future => JFuture}
     import scala.concurrent.ExecutionContext.Implicits.global
     import scala.concurrent.Future
     import scala.util.Try

     object JFuture2SFuture {
        val jFuture: JFuture[Int] = ???
        val promise = Promise[Int]()
        Future { promise.complete(Try(jFuture.get)) } //it is non blocking 
        val sFuture:Future[Int] = promise.future

     }
2
Sky

scala-Java8-compat ライブラリは、Java8とScala Futures)の間のコンバーターを提供します。

具体的には、 FutureConverters.toScala(connectionPool.getConnectionAsync()) を使用してJava.util.concurrent.Futurescala.concurrent.Futureに変換できます。

0
Sumit