16

Scala 中那些与 Future 相关的类和特征之间有什么联系,为什么它们散布在不同的包上?

我找到了那些:

abstract class scala.actors.Future
object         scala.actors.Futures
trait/object   scala.collection.parallel.FutureThreadPoolTasks
trait          scala.concurrent.FutureTaskRunner
trait          scala.parallel.Future    (the package consists of only this file...)

它们是否有明显不同的东西,还是有其他原因导致它们无法合并?

有没有一个很好的例子来展示一个人何时会使用一件事或另一件事?

编辑:赏金用于解释每个类/特征/对象的作用以及它们如何证明它们的存在/它们如何有用。

4

2 回答 2

11

scala.actors._

abstract class Future

首先,让我们看看文档是怎么说的:

一个参数为 0 的函数,返回一个 T 类型的值,当应用该值时,会阻塞当前参与者 (Actor.self),直到未来的值可用。

这基本上就是全部了。如果您正在与另一个 Actor 之外的任何地方的 Actor 通信(它可以使用sender引用接收对消息的异步回复,只需使用另一条消息)并且您需要对已发送消息的回复,您有两种选择:

  • 发送阻塞消息,等待 Actor 完成计算结果
  • 使用返回 Future 的方法发送消息,并仅在您确实需要相关值时才阻止该 Future(到那时可能已经计算出)

因此,Future 是一个占位符,用于表示尚不存在但可能在不久的将来会存在的值。以下内容也很有趣:

可以查询未来以确定其值是否已经可用而不阻塞[使用“isSet”]。

这使您可以做任何您想做的事情,直到您需要的值被计算/获取,并且您可以定期检查该值是否可用。

在深入研究 Scala 库源代码时,我发现 Futures 实际上只是演员。Future本身是一个 an abstract class,由 扩展private class FutureActor。最后一个类是实际实现-功能的类Future

object Futures

到目前为止,object Futures它并没有那么有趣,因为它只是“对未来进行操作的方法”的容器,这是一种方便的工厂方法future,它异步评估传递的块,返回代表结果的未来。一个小例子是这样的:

import scala.actors.Futures
val f = Futures.future {
    println("Start: inside block")
    val s = System.currentTimeMillis
    while(System.currentTimeMillis < (s + 1000)) {
        // Simulate computation
    }
    println("Start: end of block")
    42
}
println("After future")
println(f())
println("The end")

这应该会导致类似

Start: inside block
After future
Start: end of block
42
The end

这表明future-call 不会阻塞以下代码,直到您实际尝试检索未来的值(请注意,输出是不确定的After future也可能出现在输出的开头)。

scala.collection.parallel

这个包是 Scala 2.9.x 的新包,它为我们最喜​​欢的一些集合实现了并行对应。这些都以Par

  • ParIterable
  • ParSeq
  • 参数集
  • 参数映射

正如您可能已经知道或猜到的那样,这些集合以并行方式实现所有可能的操作,而您不必担心。一个小示范:

(1 to 10).par.map { b => print(b + " "); b * b }
3 1 6 2 7 4 5 9 10 8
    # => (1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

结果将始终相同,但处理元素的顺序又是不确定的。此外,如果您使用的是多核系统,您可能会在更大的集合中体验到不错的性能提升。

trait FutureThreadPoolTasks

FutureThreadPoolTasks特征扩展了该Tasks特征,因此让我们先看一下该特征。特质上方的评论说:

声明并行集合使用的任务执行能力的特征。

从其他源注释和Taskstrait 中的方法来看,Task 表示需要计算的工作单元。根据问题是否可以进一步分割,如果有更多可用资源,任务可以通过创建更多任务来进一步拆分任务。

现在FutureThreadPoolTaskstrait 本身只是一种计算任务的方式,它使用java.util.concurrent.Future类进行同步,也就是说,它使用scala.actors.Future! 从来源:

基于 Java 线程池 API 和使用期货的同步的任务对象的实现。

object FutureThreadPoolTasks

再次不是很壮观,只是一个包含几个(实际上只有三个)FutureThreadPoolTasks特征使用的实用方法的伴随对象。

scala.concurrent

这些类的文档非常糟糕,显然很少有(我没有找到一个)示例来演示这些类的用法。我一定会尝试收集更多关于这些的信息,并尽快扩展本节!

scala.parallel

trait Future

这似乎是“正在进行中的工作”,因为该scala.parallel包仅包含此特征。据我所知,这将与Future不使用的实现有关Actors,但这只是一个猜测。特征的签名如下

trait Future[@specialized +R] extends (() => R)

我什至不打算解释@specialized 注释变量(通用 R 类型之前的 +),但这个 trait 的基本思想是 Future 是一个函数,它在执行时返回值(并且必须因此,如果尚未计算,则阻止)。

此外,特征本身只有两种方法,applyisDone. 我的猜测是isDone,就像 , 一样scala.actors.Future.isSet,应该是一个非阻塞调用,以查看该值是否已被计算,并且该apply方法应该用于实际检索该值。

于 2011-06-15T01:04:29.030 回答
4

下面是一个简短的解释。(部分是从 scala 文档复制的)。如果您有不明白的地方,请告诉我,我会尝试更具体并给您一个具体的例子。

抽象类 scala.actors.Future - 你熟悉java.util.concorrent.Future吗?scala.actors.Future基本上代表了异步计算的结果,但对于actors

scala.actors.Futures - 一个对象(~singleton),其中包含四种用于处理scala.actors.Future的实用方法。

scala.parallel.Future ——(这对我来说是新的,但它包含非常基本的操作(apply 和 isDone))它是一个没有参数的函数,如果与函数关联的并行计算未完成,它将阻塞调用者。(功能?提示:扩展())

scala.collection.parallel.FutureThreadPoolTask ​​s -- 来自 scala 文档:“基于 Java 线程池 API 和使用期货进行同步的任务对象的实现。” 够了吗?:)

scala.concurrent.FutureTaskRunner - 你熟悉Executor吗?ExecutorScheduler是 scala 标准库中的一个(三个)具体实现。executeFromActor是更有趣的方法之一,应该提示您何时需要使用此方法

于 2011-06-12T13:15:46.793 回答