我将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/