[英]scala.concurrent.Future wrapper for java.util.concurrent.Future
I'm using Play Framework 2.1.1 with an external java library that produces a java.util.concurrent.Future result. 我正在使用Play Framework 2.1.1和一个生成java.util.concurrent.Future结果的外部Java库。 I'm using the scala future's as opposed to Akka which I think is the right thing to do as of Play 2.1.
我正在使用scala future而不是Akka,我认为这是Play 2.1的正确选择。 How can I wrap the java.util.concurrent.Future up into a scala.concurrent.Future while still keeping the code non-blocking?
如何在保持代码无阻塞的同时将java.util.concurrent.Future包装到scala.concurrent.Future中?
def geConnection() : Connection = {
// blocking with get
connectionPool.getConnectionAsync().get(30000, TimeUnit.MILLISECONDS)
}
The above code returns a connection but uses a get so it becomes blocking 上面的代码返回一个连接,但使用了get,所以它变成了阻塞
def getConnectionFuture() : Future[Connection] = {
future {
// how to remove blocking get and return a scala future?
connectionPool.getConnectionAsync().get(30000, TimeUnit.MILLISECONDS)
}
}
Ideally I want a scala function that returns the connection as a future like the code above but without the code blocking via the get. 理想情况下,我想要一个scala函数,它返回连接作为未来,如上面的代码,但没有通过get阻止代码。 What else do I need to put into the function to make it non blocking.
我需要在函数中添加什么才能使其无阻塞。
Any pointers would be great. 任何指针都会很棒。
import java.util.concurrent.{Future => JFuture}
import scala.concurrent.{Future => SFuture}
You can't wrap JFuture
with SFuture
without blocking since there is a callback in SFuture
( onComplete
) and there is only blocking get
in JFuture
. 你不能在没有阻塞的情况下用
SFuture
包装JFuture
,因为在SFuture
有一个回调( onComplete
)并且在JFuture
只有阻塞get
。
All you can do is to create additional thread and block it with get
, then complete Promise
with result of get
. 所有你能做的是创造更多的线程,并阻止它
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
You could check isDone
in endless loop, but I don't think it is better then blocking. 你可以在无限循环中检查
isDone
,但我不认为它比阻塞更好。
Future {
blocking {
jfuture.get
}
}
This lets the ExecutionContext know that what you are doing is going to block, giving it a chance to allocate more threads. 这使得ExecutionContext知道你正在做的事情将会阻塞,让它有机会分配更多的线程。 If you do not include
blocking { }
then you may run out of threads. 如果您不包含
blocking { }
那么您可能会用尽线程。
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
}
The scala-java8-compat library provides converters between java8 and Scala Futures. scala-java8-compat库提供java8和Scala Futures之间的转换器。
Specifically, you can use FutureConverters.toScala(connectionPool.getConnectionAsync())
to convert the java.util.concurrent.Future
to scala.concurrent.Future
具体来说,您可以使用
FutureConverters.toScala(connectionPool.getConnectionAsync())
将java.util.concurrent.Future
转换为scala.concurrent.Future
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.