我将Play Framework 2.1.1与产生java.util.concurrent.Future结果的外部Java库一起使用。我使用的是scala future,而不是Akka,我认为从Play 2.1开始,这是正确的做法。我如何将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)
  }
}

理想情况下,我想要一个scala函数,该函数可以像上面的代码一样将连接作为将来返回,但不会通过get阻塞代码。我还需要在函数中添加其他内容以使其不阻塞。

任何指针都很棒。

最佳答案

import java.util.concurrent.{Future => JFuture}
import scala.concurrent.{Future => SFuture}

您不能在不阻塞的情况下用 JFuture 包裹 SFuture ,因为SFuture(onComplete)中有一个回调,而在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,但我认为阻塞比它更好。

关于java - java.util.concurrent.Future的scala.concurrent.Future包装器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17215421/

10-09 02:56