Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
推特';s Future.collect不同时工作(Scala)_Scala_Concurrency_Twitter Util - Fatal编程技术网

推特';s Future.collect不同时工作(Scala)

推特';s Future.collect不同时工作(Scala),scala,concurrency,twitter-util,Scala,Concurrency,Twitter Util,我来自node.js背景,对Scala不熟悉,我尝试使用Twitter的Future.collect执行一些简单的并发操作。但我的代码显示的是顺序行为,而不是并发行为。我做错了什么 这是我的密码 import com.twitter.util.Future def waitForSeconds(seconds: Int, container:String): Future[String] = Future[String] { Thread.sleep(seconds*1000) pr

我来自node.js背景,对Scala不熟悉,我尝试使用Twitter的Future.collect执行一些简单的并发操作。但我的代码显示的是顺序行为,而不是并发行为。我做错了什么

这是我的密码

import com.twitter.util.Future

def waitForSeconds(seconds: Int, container:String): Future[String]  = Future[String] {
  Thread.sleep(seconds*1000)
  println(container + ": done waiting for " + seconds + " seconds")
  container + " :done waiting for " + seconds + " seconds"
}

def mainFunction:String = {
  val allTasks = Future.collect(Seq(waitForSeconds(1, "All"), waitForSeconds(3, "All"), waitForSeconds(2, "All")))
  val singleTask = waitForSeconds(1, "Single")

  allTasks onSuccess  { res =>
    println("All tasks succeeded with result " + res)
  }

  singleTask onSuccess { res =>
    println("Single task succeeded with result " + res)
  }

  "Function Complete"
}

println(mainFunction)
这是我得到的输出

All: done waiting for 1 seconds
All: done waiting for 3 seconds
All: done waiting for 2 seconds
Single: done waiting for 1 seconds
All tasks succeeded with result ArraySeq(All :done waiting for 1 seconds, All :done waiting for 3 seconds, All :done waiting for 2 seconds)
Single task succeeded with result Single :done waiting for 1 seconds
Function Complete
我期望的结果是

All: done waiting for 1 seconds
Single: done waiting for 1 seconds
All: done waiting for 2 seconds
All: done waiting for 3 seconds
All tasks succeeded with result ArraySeq(All :done waiting for 1 seconds, All :done waiting for 3 seconds, All :done waiting for 2 seconds)
Single task succeeded with result Single :done waiting for 1 seconds
Function Complete

Twitter的未来比Scala标准库的未来更明确地说明了计算的执行位置。特别是,
Future.apply
将安全地捕获异常(如
s.c.Future
),但它没有说明计算将在哪个线程中运行。在你的例子中,计算是在主线程中运行的,这就是你看到结果的原因

与标准库未来的API相比,这种方法有几个优点。首先,它使方法签名更简单,因为不存在必须到处传递的隐式
ExecutionContext
。更重要的是,它使避免上下文切换变得更容易(Brian Degenhardt)。在这方面,Twitter的
未来
更像Scalaz的
任务
,本质上具有相同的性能优势(如中所述)

更明确地说明计算在哪里运行的缺点是,必须更明确地说明计算在哪里运行。在你的情况下,你可以这样写:

import com.twitter.util.{ Future, FuturePool }

val pool = FuturePool.unboundedPool

def waitForSeconds(seconds: Int, container:String): Future[String] = pool {
  Thread.sleep(seconds*1000)
  println(container + ": done waiting for " + seconds + " seconds")
  container + " :done waiting for " + seconds + " seconds"
}
这不会精确地生成您要求的输出(“函数完成”将首先打印,并且
所有任务
单个任务
不会相互排序),但它将在单独的线程上并行运行任务


(作为脚注:在我上面的示例中,
FuturePool.unboundedPool
是为演示创建未来池的一种简单方法,通常很好,但它不适合CPU密集型计算,请参阅其他创建未来池的方法,该池将使用您提供的并可以自己管理的
ExecutorService

好吧,一个
未来
的关键在于将计算转移到另一个线程。因此,在main函数的第一行中,将生成三个新线程,当生成的线程完成时,将生成另一个线程来执行oncomplete函数。在第二行中,生成了另一个线程,并将与其他线程并行执行。因此,我认为实际输出似乎是有效的…非常好!我使用了您的代码,并在最后一行添加了Thread.sleep(6000),现在我看到了并发行为。进行更改后的输出为,
功能完成
全部:完成等待1秒
单个:完成等待1秒
单个任务成功,结果单个:完成等待1秒
全部:完成等待2秒
全部:完成等待3秒
所有任务成功,结果为ArraySeq(All:done waiting 1秒,All:done waiting 3秒,All:done waiting 2秒)
添加更多内容。Twitter futures上最近发布的一篇文档解释了一些设计决策:(com.Twitter.util.)wait.result(allTasks)可能比Thread.sleep(6000)更好