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
我的问题与评论中提出的问题相同:
未来有什么问题?为什么你使用额外的线程与Promise结合?
答案如下:
它会阻止线程拉动中的线程 . 如果您为这样的期货配置了ExecutionContext,那很好,但是默认的ExecutionContext包含与处理器一样多的线程 .
我不确定我理解这个解释 . 重申:
future { jfuture.get }
有什么问题?在手中创建一个新线程并在那里阻塞时,在未来内部是否阻塞?如果没有,它有什么不同?
2 回答
future { jfuture.get }
和future { future { jfuture.get }}
之间几乎没有区别 .默认线程池中有许多踏板,因为有许多处理器 .
使用
jfuture.get
,您将获得1个线程被阻止 .设's assume you have 8 processors. Also let'假设每个
jfuture.get
需要10秒钟 . 现在创建8future { jfuture.get }
.对于
2+2
评估,10秒有点太长了 .所有其他
future
和同一执行上下文中的所有actor将被停止10秒 .附加执行上下文:
您可以使用
new Thread(new Runnable {...
实现blockingFuture
,但是额外的执行上下文允许您限制线程数 .它实际上非常简单 .
scala.concurrent.Promise
是Future
的具体实现,注定是异步计算 .当您想要转换时,使用
jfuture.get
,您正在运行阻塞计算并输出立即解析的scala.concurrent.Future
.Thread
将阻塞,直到jfuture
内的计算完成 .get
方法正在阻止 .阻塞意味着在计算完成之前,其他任何内容都不会发生 . 你本质上是在垄断
Thread
,看起来像是一个间歇性地检查结果的while
循环 .特别:
当阻塞无法避免时,通常的做法是生成
new Thread
和new Runnable
或new Callable
以允许计算执行/独占子线程 .在示例中@senia给出:
这与
future {jfuture.get}
有什么不同?它不会阻止由Scala提供的默认值ExecutionContext
,它具有与机器处理器一样多的线程 .这意味着代码中的所有其他期货将始终等待
future { jfuture.get }
完成,因为整个上下文被阻止 .