簡體   English   中英

Scala中多個Futures的奇怪案例

[英]The strange case of multiple Futures in Scala

那些與 Future 相關的 class 和 Scala 中的特征之間有什么聯系,為什么它們會散布在不同的包上?

我找到了那些:

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...)

它們是否有明顯不同的東西,還是有其他原因導致它們無法合並?

有沒有一個很好的例子來展示一個人何時會使用一件事或另一件事?

編輯:賞金用於解釋每個類/特征/對象的作用以及它們如何證明它們的存在/它們如何有用。

scala.actors._

abstract class Future

首先,讓我們看看文檔是怎么說的:

一個 arity 0 的 function,返回一個類型為 T 的值,當應用該值時,會阻塞當前的actor (Actor.self),直到未來的值可用。

這基本上就是全部了。 如果您正在與另一個 Actor 之外的任何地方的 Actor 通信(它可以使用sender引用簡單地通過另一條消息接收對消息的異步回復)並且您需要對已發送消息的回復,您有兩種選擇:

  • 發送一條阻塞消息,等待 Actor 完成計算您的結果
  • 使用返回 Future 的方法發送消息,並僅在您確實需要相關值時才阻止該 Future(到那時可能已經計算出)

因此,Future 是一個占位符,用於表示尚不存在但可能在不久的將來會存在的值。 以下內容也很有趣:

可以查詢未來以確定其值是否已經可用而不阻塞[使用“isSet”]。

這使您可以做任何您想做的事情,直到您需要的值被計算/獲取,並且您可以定期檢查該值是否可用。

在深入研究 Scala 庫源代碼時,我發現 Futures 實際上只是演員。 Future本身是一個abstract class ,由private class FutureActor 最后一個 class 是實際實現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 的值之前, future -call 不會阻塞以下代碼(注意 output 是non-deterministic 。future After future也可能出現在輸出的開頭)。

scala.collection.parallel

該軟件包是 Scala 2.9.x 的新軟件包,並為我們最喜歡的一些 collections 實現了並行對應項。 這些都以Par開頭:

  • ParIterable
  • ParSeq
  • 參數集
  • 參數映射

您可能已經知道或猜到了,這些 collections 以並行方式實現所有可能的操作,而您不必擔心。 一個小示范:

(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)

結果將始終相同,但處理元素的順序又是不確定的。 此外,如果您在多核系統上,您可能會體驗到更大的 collections 的性能提升。

trait FutureThreadPoolTasks

FutureThreadPoolTasks trait 擴展了Tasks trait,所以讓我們先來看看它。 特質上方的評論說:

聲明並行 collections 使用的任務執行能力的特征。

從其他源注釋和Tasks trait 中的方法來看,Task 表示需要計算的工作單元。 根據問題是否可以進一步分割,如果有更多可用資源,任務可以通過創建更多任務來進一步拆分任務。

現在FutureThreadPoolTasks trait 本身只是一種計算任務的方式,它使用java.util.concurrent.Future class 進行同步,也就是說,它使用scala.actors.Future

基於 Java 線程池 API 和使用期貨同步的任務對象的實現。

object FutureThreadPoolTasks

再一次不是很壯觀,只是一個配套的 object 包含FutureThreadPoolTasks特征使用的幾個(實際上只有三個)實用程序方法。

scala.concurrent

這些類的文檔非常糟糕,顯然很少有(我沒有找到一個)示例來演示這些類的用法。 我一定會嘗試收集更多關於這些的信息,並盡快擴展本節!

scala.parallel

trait Future

這似乎是“正在進行的工作”,因為scala.parallel package 僅包含此特征。 據我所知,這將與不使用ActorsFuture實現有關,但這只是一個猜測。 特征的簽名如下

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

我什至不打算解釋@specialized 注釋差異(通用 R 類型之前的 +),但這個特征的基本思想是 Future 是 function ,它在執行時返回值(並且必須因此,如果尚未計算,則阻止)。

此外,特征本身只有兩個方法, applyisDone 我的猜測是isDone ,就像scala.actors.Future.isSet一樣,應該是一個非阻塞調用來查看是否已經計算了值,並且應該使用apply方法來實際檢索該值。

下面是一個簡短的解釋。 (零件復制自 scala 文檔)。 如果您有不明白的地方,請告訴我,我會嘗試更具體並給您一個具體的例子。

摘要 class scala.actors.Future -- 你熟悉java.util.concorrent.Future嗎? scala.actors.Future基本上代表了異步計算的結果,但對於actors

scala.actors.Futures -- 一個 object (~singleton) 包含四種處理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. (功能?提示:擴展())

scala.collection.parallel.FutureThreadPoolTasks -- From the scala doc: "An implementation of tasks objects based on the Java thread pooling API and synchronization using futures." 夠了嗎? :)

scala.concurrent.FutureTaskRunner -- 你熟悉Executor嗎? ExecutorScheduler是 scala 標准庫中的一個(三個)具體實現。 executeFromActor是更有趣的方法之一,應該提示您何時需要使用此方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM