在Scala 2.10中使用期货。他们是Scala团队,Akka团队和Twitter之间的共同工作,以期实现更加标准化的未来API和实现,以供跨框架使用。我们刚刚在以下网站发布了指南:http://docs.scala-lang.org/overviews/core/futures.html
除了完全非阻塞(默认情况下,尽管我们提供了执行托管阻塞操作的能力)和可组合性之外,Scala的2.10期货还带有隐式线程池来执行任务,以及一些用于管理超时的实用程序。
import scala.concurrent.{future, blocking, Future, Await, ExecutionContext.Implicits.global}
import scala.concurrent.duration._
val urls: List[String] = ...
val imagesFuts: List[Future[...]] = urls.map {
url => future { blocking { download url } }
}
val futImages: Future[List[...]] = Future.sequence(imagesFuts)
Await.result(futImages, 10 seconds).foreach(display)
上面,我们首先导入一些东西:
future
:用于创建未来的API。
blocking
:用于托管阻止的API。
Future
:期货伴随对象,其中包含许多有用的期货收集方法。
Await
:用于阻止将来的单例对象(将其结果传输到当前线程)。
ExecutionContext.Implicits.global
:默认的全局线程池,一个ForkJoin池。
duration._
:用于管理超时时间的实用程序。
imagesFuts
仍与您最初所做的大致相同-唯一的区别是我们使用了托管阻止- blocking
。它通知线程池您传递给它的代码块包含长时间运行或阻塞的操作。这允许池临时产生新的工作程序,以确保所有工作程序都不会被阻塞。这样做是为了防止阻塞应用程序中的饥饿(锁定线程池)。请注意,线程池还知道托管阻塞块中的代码何时完成-因此它将在该点删除备用工作线程,这意味着该池将缩小到其预期大小。
(如果要绝对防止创建其他线程,则应使用AsyncIO库,例如Java的NIO库。)
然后,我们用未来的伴侣要转换的对象的收集方法imagesFuts
,从 List[Future[...]]
到Future[List[...]]
。
该Await
对象是我们如何确保display
在调用Await.result
线程上执行的对象,只需强制当前线程等待,直到将来通过它为止即可。(这在内部使用托管阻止。)
ExecutionContext
来强制完成回调(而不是实际的后台进程)在特定线程(即UI线程,使用特定于框架的方法)上异步执行?