Подтвердить что ты не робот

Scala.concurrent.Future обертка для java.util.concurrent.Future

Я использую Play Framework 2.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. Что еще мне нужно, чтобы включить функцию, чтобы она не блокировалась.

Любые указатели будут замечательными.

4b9b3361

Ответ 1

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

Вы не можете обернуть JFuture с SFuture без блокировки, так как есть обратный вызов в SFuture (onComplete) и блокируется только get в JFuture.

Все, что вы можете сделать, это создать дополнительный поток и заблокировать его с помощью 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

Future {
  blocking {
    jfuture.get
  }
}

Это позволяет ExecutionContext знать, что то, что вы делаете, блокируется, предоставляя ему возможность выделять больше потоков. Если вы не включили blocking { }, тогда у вас может закончиться поток.

Ответ 3

     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

     }