2013-06-20 60 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 

    }