我正在使用Play Framework2.1.1和一个外部java库,它会产生一个java.util.concurrent.Future结果。我使用的是scala的未来,而不是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阻塞代码。我还需要在函数中放入什么才能使其非阻塞。
任何指针都会很棒。
发布于 2013-06-20 22:01:09
import java.util.concurrent.{Future => JFuture}
import scala.concurrent.{Future => SFuture}你不能在没有阻塞的情况下用SFuture包装JFuture,因为在SFuture (onComplete)中有一个回调,而在JFuture中只有阻塞的get。
你所能做的就是创建额外的线程并用get阻塞它,然后用get的结果来完成Promise。
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,但我不认为它比阻塞更好。
发布于 2016-02-26 03:13:41
Future {
blocking {
jfuture.get
}
}这让ExecutionContext知道你正在做的事情将要阻塞,给它一个分配更多线程的机会。如果不包含blocking { },则可能会用完所有线程。
发布于 2017-12-03 18:03:12
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
}https://stackoverflow.com/questions/17215421
复制相似问题