2013-06-20 72 views
20

我使用Play Framework 2.1.1与外部java库产生java.util.concurrent.Future结果。我正在使用Scala未来版本,而不是Akka,我认为这是Play 2.1的正确选择。如何将java.util.concurrent.Future包装到scala.concurrent.Future中,同时仍然保持代码不被阻塞?scala.concurrent.Future封装java.util.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。我还需要将其放入函数中以使其不被阻塞。

任何指针都会很棒。

+0

您正在使用哪个斯卡拉的版本转换?截至2.10.x,Scala采用了Akka的Future作为自己的未来。 –

+0

Play 2.1.1使用Scala 2.10.0下盖 –

回答

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

你不能换JFutureSFuture不会阻塞,因为在SFutureonComplete)回调,并且只有在JFuture阻塞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 

你可以在无限循环检查isDone,但我不认为这是更好然后阻塞。

+2

同意。总耻辱的Java未来的不支持某种完成监听器/观察员回调 – cmbaxter

+0

@cmbaxter如果使用番石榴,还有'ListenableFuture' – fge

+0

所以我沿着回调为java peice的线条想,当完成后,它的结果将在scala未来。回顾一下在Java中实现的回调示例(http://technology.amis.nl/2009/02/19/asynchronous-processing-in-java-applications-leveraging-those-multi-cores/),但没有确定如何将其转换为Play 2.1。乐观地说,我希望得到一个简单的包装,但它看起来并不可行,而且在scala函数中的一个java回调看起来很不错。 –

2
Future { 
    blocking { 
    jfuture.get 
    } 
} 

这让ExecutionContext知道你正在做什么会阻塞,给它一个分配更多线程的机会。如果你不包括blocking { }那么你可能会用尽线程。

+0

您可能希望提供有关这些优点/缺点的详细信息。是否与上面讨论的完全相同(例如来自@senia的评论) – akauppi

+1

对不起。添加了一条评论来解释“阻止”的使用。 –

+1

如果你做'阻塞',那么你可能会在成千上万的高负载线程结束。小心 - '阻塞'不是魔术! – folex

1
 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 

    }