This answer指示如何将java.util.concurrent.Future转换为scala.concurrent.Future,同时管理将在何处发生阻塞:

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

val jfuture: JFuture[T] = ???
val promise = Promise[T]()
new Thread(
  new Runnable {
    def run() { promise.complete(Try{ jfuture.get }) }
  }
).start
val future = promise.future

我的问题与评论中的问题相同:



回答如下:



我不确定我是否理解其中的解释。重申:
future { jfuture.get }有什么问题?在将来的内部进行阻塞与手动创建新线程并在其中进行阻塞不一样吗?如果没有,那有什么不同?

最佳答案

future { jfuture.get }future { future { jfuture.get }}之间几乎没有区别。

默认线程池中的缓冲区数与您拥有的处理器数一样多。

使用jfuture.get,您将获得1个线程被阻止。

假设您有8个处理器。还要假设每个jfuture.get花费10秒。现在创建8 future { jfuture.get }

val format = new java.text.SimpleDateFormat("HH:mm:ss").format(_: Date)

val startTime = new Date
(1 to 8) map {_ => future{ Thread.sleep(10000) }}
future{
  2+2
  println(s"2+2 done. Start time: ${format(startTime)}, end time: ${format(new Date)}")
}

// 2+2 done. Start time: 20:48:18, end time: 20:48:28

10秒钟对于2+2评估来说太长了。

同一执行上下文中的所有其他future和所有actor将停止10秒钟。

带有其他执行上下文:
object BlockingExecution {
  val executor = ExecutionContext.fromExecutor(new ForkJoinPool(20))
}

def blockingFuture[T](f: => T) = {
  future( f )(BlockingExecution.executor)
}

val startTime = new Date
(1 to 8) map {_ => blockingFuture{ Thread.sleep(10000) }}
future{
  2+2
  println(s"2+2 done. Start time: ${format(startTime)}, end time: ${format(new Date)}")
}

// 2+2 done. Start time: 21:26:18, end time: 21:26:18

您可以使用blockingFuture实现new Thread(new Runnable {...,但其他执行上下文允许您限制线程数。

09-11 18:37