我正在编写围绕java库的小型scala包装。ListenableFuture to scala未来
Java库的目的QueryExecutor曝光2种方法:
- 执行(查询):结果
- asyncExecute(查询):ListenableFuture [结果]
ListenableFuture在这种情况下是一个来自番石榴图书馆。
我想我的scala包装返回Future [结果]而不是java对象,但我不知道什么是最好的实现方式。这里有两个解决方案,我想出了:
future {
executor.execute(query)
}
和
val p = promise[Result]
val guavaFuture = executor.asyncExecute(query)
Futures.addCallback(guavaFuture, new FutureCallback[Result] {
def onFailure(t: Throwable) {
p.failure(t)
}
def onSuccess(result: Result) {
p.success(result)
}
})
p.future
我想知道哪种方法是最好的。我的直觉是,第一个在返回Future时,仍然会阻塞一个线程,而执行调用等待响应,第二个看起来应该是非阻塞的。对每种方法的优缺点有何评论?
假设您有4个处理器。在这种情况下,默认的'ExecutionContext'由4名工人组成。每个'future {executor.execute(query)}'会阻止1个worker,所以4个“futures”将完全阻止你的程序。你可以为阻塞操作创建额外的'ExecutionContext',但是会有一些开销。 – senia
谢谢@senia,这就是我的想法。第一个代码从调用者的角度来看是异步的,但仍然会阻塞ExecutionContext的线程,而第二个代码实际上是非阻塞的(假设asyncExecute使用非阻塞IO)。我觉得这是一个非常基本的问题,但我对Promises不是很熟悉。 – vptheron
我发现这对于类似(甚至可能相同)的需求是有帮助的:https://github.com/eigengo/activator-akka-cassandra/blob/master/src/main/scala/core/cassandra.scala – Gavin