Scala 中多个 Future 的奇怪情况
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...)
它们是否有显着不同的事情,或者是否有其他原因导致它们无法合并?
有没有一个很好的例子来说明何时使用其中一种或另一种?
编辑:奖励解释每个类/特征/对象的作用以及它们如何证明其存在的合理性/它们如何有用。
What's the the connection between those Future-related class and traits in Scala, and why are they sprinkled over different packages?
I have found those:
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...)
Do they significantly different things or is there another reason why they can't be consolidated?
Is there a good example showing when one would use the one thing or the other?
Edit: Bounty for explaining what each of the classes/traits/objects does and how they justify their existance/how they are useful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
scala.actors._
abstract class Future
首先,让我们看看文档是怎么说的:
这基本上就是全部了。如果您从另一个 Actor 之外的任何地方与 Actor 进行通信(它可以使用
sender
引用简单地通过另一条消息接收对消息的异步回复)并且您需要对已发送消息的回复,那么您可以有两种选择:Future 是一个尚未存在但可能在不久的将来会存在的值的占位符。下面的内容也很有趣:
这允许您做任何您想做的事情,直到计算/获取您需要的值,并且您可以定期检查该值是否可用。
当深入研究 Scala 库源代码时,我发现 Futures 实际上只是参与者。
Future
本身是一个抽象类
,由私有类FutureActor
扩展。最后一个类是实际实现Future
功能的类。object Futures
到目前为止,
object Futures
并不那么有趣,因为它仅仅是“操作 futures 的方法”的容器,方便的工厂方法future
异步评估传递的块,返回代表结果的 future。一个小例子是这样的:这应该会导致类似的结果
这表明
future
调用不会阻止以下代码,直到您实际尝试检索 future 的值(请注意,输出是非确定性也可能出现在开头。输出)。scala.collection.parallel
这个包是 Scala 2.9.x 中的新包,它为我们最喜欢的一些集合实现了并行对应项。这些都以
Par
开头:您可能已经知道或猜到,这些集合以并行方式实现所有可能的操作,而您无需担心。一个小演示:
结果始终是相同的,但处理元素的顺序又是不确定的。此外,如果您使用的是多核系统,对于较大的集合,您可能会体验到良好的性能提升。
trait FutureThreadPoolTasks
FutureThreadPoolTasks
特征扩展了Tasks
特征,所以让我们先看一下这个特征。该特征上方的评论说:从其他源注释和
Tasks
特征中找到的方法来看,任务表示需要计算的工作单元。根据问题是否可以进一步划分,以及如果有更多可用资源,任务可以通过创建更多任务来进一步拆分任务。现在,FutureThreadPoolTasks 特性本身只是一种计算任务的方法,它使用 java.util.concurrent.Future 类进行同步,也就是说,它确实不要使用
scala.actors.Future
!从源头看:object FutureThreadPoolTasks
再次不是很引人注目,只是一个伴随对象,其中包含
FutureThreadPoolTasks
特征使用的一些(实际上只有三个)实用程序方法。scala.concurrent
关于这些类的文档非常糟糕,而且显然很少有(我没有找到一个)示例来演示这些类的用法。我一定会尽力收集更多有关这些的信息,并尽快扩展本节!
scala.parallel
trait Future
这似乎是一个“正在进行中的工作”,因为
scala.parallel
包仅包含此特征。据我所知,这将与不使用Actors
的Future
实现相关,但这只是一个猜测。该特征的签名如下,我什至不打算尝试解释 @specialized 注释 或 变体(通用 R 类型之前的 +),但这个特征的基本思想是,Future 是一个函数,在执行时返回值(如果尚未计算,则必须阻塞)。
此外,特征本身内部只有两个方法,
apply
和isDone
。我的猜测是,isDone 就像 scala.actors.Future.isSet 一样,应该是一个非阻塞调用,以查看值是否已计算出来,并且应该使用apply
方法来实际检索该值。scala.actors._
abstract class Future
First of all, lets see what the documentation says:
And that is basically all there is. If you are communicating with an Actor from anywhere outside of another actor (which can receive asynchronous replies to messages simply with another message, using the
sender
reference) and you need the reply to a sent message, you have two choices:So a Future is a placeholer for a value which does not yet exist, but probably will in the near future. The following is also interesting:
This allows you to do whatever you want until the value you need has been computed/fetched, and you can periodically check if the value has become available.
When digging a bit into the Scala library source code, I found out that Futures are actually just actors.
Future
itself is a anabstract class
, which is extended by theprivate class FutureActor
. This last class is the one that actually implements theFuture
-functionality.object Futures
The
object Futures
is by far not as interesting, as it is merely a container for the "Methods that operate on futures", the handy factory methodfuture
which asynchronously evaluates the passed block, returning a future representing the result. A small example would be this:Which should result in something like
This demonstrates that the
future
-call does not block the following code until you actually try to retrieve the value of the future (note that the output is non-deterministic.After future
could also appear at the beginning of the output).scala.collection.parallel
This packages is new to Scala 2.9.x and implements parallel counterparts for some of our favorite collections. These all start with
Par
:As you may have known or guessed already, these collections implement all possible operations in a parallel manner without you having to worry about it. A small demonstration:
The result will always be the same, but the order in which the elements are processed is again non-deterministic. Also, if you are on a multicore system, you will probably experience a nice performance boost for larger collections.
trait FutureThreadPoolTasks
The
FutureThreadPoolTasks
trait extends theTasks
trait, so lets take a look at that one first. The comment above the trait says:Judging from the other source comments and the methods found in the
Tasks
trait, a Task represents a unit of work which needs to be computed. Depending on wether or not a problem is divisible further and if there are more resources available, a Task can split up a Task further by creating more tasks.Now the
FutureThreadPoolTasks
trait itself is just a way to compute tasks, which uses thejava.util.concurrent.Future
class for its synchronization, that is, it does not usescala.actors.Future
! From the source:object FutureThreadPoolTasks
Once again not very spectacular, just a companion object containing a few (actually only three) utility methods which the
FutureThreadPoolTasks
trait uses.scala.concurrent
The documentation on these classes is really bad and apparently there are very few if any (I didn't find a single one) examples which demonstrate the usage of these classes. I will definitely try to gather more information on these and expand on this section as soon as I can!
scala.parallel
trait Future
This seems to be a "Work in progess", as the
scala.parallel
package only contains this trait. From what I can tell, this is going to be related to aFuture
implementation which does not useActors
, but that is just a guess. The signature of the trait is the followingI am not even going to try to explain the @specialized annotation or variances (the + before the generic R type), but the basic idea in this trait is that a Future is a function which, when executed, returns the value (and must therefor block if it has not been computed yet).
Also, there are only two methods inside the trait itself,
apply
andisDone
. My guess is thatisDone
, just like thescala.actors.Future.isSet
, is supposed to be a non-blocking call to see if the value has been computed, and theapply
method should be used to actually retrieve the value.下面是一个简单的解释。 (部分内容是从 scala 文档复制的)。如果您有不明白的地方,请告诉我,我会尽力更具体,并给您一个具体的例子。
抽象类scala.actors.Future -- 你熟悉java.util.concorrent.Future? scala.actors.Future 基本上表示异步计算的结果,但对于 actors 来说。
scala.actors.Futures -- 一个对象 (~singleton),包含四个用于处理 scala.actors.Future 的实用方法。
scala.parallel.Future --(这对我来说是新的,但它包含非常基本的操作(apply 和 isDone))它是一个没有参数的函数,如果与以下内容相关的并行计算将阻止调用者功能未完成。 (函数?提示:extends())
scala .collection.parallel.FutureThreadPoolTasks -- 来自 scala 文档:“基于 Java 线程池 API 和使用 future 进行同步的任务对象的实现。”够了吗? :)
scala.concurrent.FutureTaskRunner -- 你熟悉执行器? ExecutorScheduler 是 scala 标准库中的一个(三分之一)具体实现。 executeFromActor 是更有趣的方法之一,应该会提示您何时需要使用此方法
Below is a brief explanation. (Parts are copied from the scala doc). Let me know if there is something that you dont understand and I will try to be more specific and give you a concrete example.
abstract class scala.actors.Future -- Are you familiar with java.util.concorrent.Future? scala.actors.Future basically represents the result of an asynchronous computation but for actors.
scala.actors.Futures -- An object (~singleton) that contains four utility methods for handling scala.actors.Future.
scala.parallel.Future -- (This one was new to me, but it contains very basic operations (apply and isDone)) its a function without parameters that will block the caller if the parallel computation associated with the function is not completed. (function? hint: extends () )
scala.collection.parallel.FutureThreadPoolTasks -- From the scala doc: "An implementation of tasks objects based on the Java thread pooling API and synchronization using futures." Is that enough? :)
scala.concurrent.FutureTaskRunner -- Are you familiar with Executor? ExecutorScheduler is one (out of three) concrete implementations in the scala standard library. executeFromActor is one of the more interesting methods and should give you a hint about when you need to use this one