Multithreading scala中的多线程

Multithreading scala中的多线程,multithreading,scala,Multithreading,Scala,我最近在学校里遇到了一个挑战,要用Scala创建一个简单的程序,在矩阵中做一些计算,问题是我必须用5个线程来做这些计算,因为我以前不知道Scala,所以我被卡住了。我在网上搜索,但没有找到如何创建所需的确切线程数。代码如下: import scala.math object Test{ def main(args: Array[String]){ val M1: Seq[Seq[Int]] = List( List(1, 2, 3), List(4, 5

我最近在学校里遇到了一个挑战,要用Scala创建一个简单的程序,在矩阵中做一些计算,问题是我必须用5个线程来做这些计算,因为我以前不知道Scala,所以我被卡住了。我在网上搜索,但没有找到如何创建所需的确切线程数。代码如下:

import scala.math

object Test{

  def main(args: Array[String]){

    val M1: Seq[Seq[Int]] = List(
      List(1, 2, 3),
      List(4, 5, 6),
      List(7, 8, 9)
    )

    var tempData : Float= 0
    var count:Int = 1
    var finalData:Int=0

    for(i<-0 to M1.length-1; j<-0 to M1(0).length-1){

      count = 1

      tempData = M1(i)(j)+ calc(i-1,j)+calc(i,j-1)+calc(i+1,j)
      finalData = math.ceil(tempData/count).toInt
      printf("%d ", finalData)
    }

    def calc(i:Int, j:Int): Int ={

      if((i<0)|| (j<0) || (i>M1.length-1))
        return 0

      else{
        count +=1
        return M1(i)(j)}
      }
    }
导入scala.math
对象测试{
def main(参数:数组[字符串]){
val M1:Seq[Seq[Int]]=列表(
清单(1,2,3),
清单(4,5,6),
名单(7、8、9)
)
变量tempData:Float=0
变量计数:Int=1
var finalData:Int=0

因为(i我不是专家,既不是Scala专家,也不是并发专家。
Scala实现并发的方法是通过使用actors和消息传递,您可以在这里了解一些(第一版是免费的,但已经过时)。正如我所说的,该版本已经过时,在Scala的最新版本(2.12)中,actors库不再包括在内,他们建议您使用Akka,您可以阅读


因此,我不建议仅仅为了挑战而学习Scala、Sbt和Akka,但您可以下载Akka快速入门,并根据您的需要定制示例,链接中对此进行了很好的解释。参与者的每个实例都有自己的线程。您可以阅读关于参与者和线程的内容,特别是关于状态的部分。

这里是t他是计算的原始核心

for(i<-0 to M1.length-1; j<-0 to M1(0).length-1){

  count = 1

  tempData = M1(i)(j)+ calc(i-1,j)+calc(i,j-1)+calc(i+1,j)
  finalData = math.ceil(tempData/count).toInt
  printf("%d ", finalData)
}
接下来,对
产生副作用的
也有一点代码味道。因此,在内部循环中,让我们生成每一行,在外部循环中生成一个行列表

val R = for (i <- 0 to M1.length - 1) yield {
  for (j <- 0 to M1(0).length - 1) yield {

    val tempList = List(Some(M1(i)(j)), calc(i - 1, j), calc(i, j - 1), calc(i + 1, j)).flatten
    math.ceil(tempList.sum / tempList.length).toInt
  }
}
这是我们的
singlethread
。要使它并行,我们只需

val R = (0 until M1.length).par.map { i =>
  (0 until M1(0).length).par.map { j =>

    val tempList = List(Some(M1(i)(j)), calc(i - 1, j), calc(i, j - 1), calc(i + 1, j)).flatten
    math.ceil(tempList.sum / tempList.length).toInt
  }.seq
}.seq
这是我们的
MotionBlurMultiThread
。它的功能也很好(没有可变值)


Github的挑战不是限制5个或10个线程,但是如果你需要这样做,你可以看看和相关的问题。

旁注:你似乎添加了不必要的类型注释,这会损害可读性,例如
var count:Int=1
=>
var count=1
好的,谢谢,这实际上是我学习scala的第一天,所以我很高兴我还不知道所有的最佳实践
a是的,我试过了,它成功了,实际上挑战是创建一个单线程版本和多线程版本@niceman“因为我以前不知道Scala,我被卡住了。”我认为上学的目的是学习、学习,然后能够做新的事情。我真的不明白为什么会有人参加课程,然后找其他人为他们做作业。对不起,我真的尽量不这样做,但即使有最新版本(收费)我认为免费版对于Scala开发者来说是一个常见的学习资源,并且大多数概念仍然有效。在这种情况下,重要的是说它已经过时了,因为库已经不存在了,但是使用新的Akka库这种方法仍然有效。参与者是Scala中并发的一种方法。并行集合是另外,期货是另一个.Stream(Fs2,scalaz.streams)还有一个。更不用说为Java并发编写的所有内容都是可用的。因此,您的回答是错误的。我从来没有说过我的解决方案是详尽无遗的。我首先澄清我不是专家,我仍然相信这是推荐的方法。当然,您可以使用Java中可用的所有内容,但为什么不坚持使用Java呢,我认为你应该写一个改进的答案来启发我们。“Scala并发方法是通过使用参与者和消息传递,你可以在这里读一点,…”如果你搜索“Scala并发方法”,我认为这是有效的在搜索引擎上,搜索结果的顶部会有参与者,也许我应该告诉他们最常用的方法,或者是许多方法中的一种,我也没有说这是唯一的方法。说这是一种方法并不意味着禁止任何其他方法,只是这是一种常见的做法,如果有人不熟悉有些主题正在寻找快速答案,我认为可用信息方面的支持是一个很好的标准。但我下次会尝试更具体一些。代码运行得很好,只是它给了我错误的结果。它应该给我(3,3,4)(4,5,6)(6,7,8),但它给了我(2,2,3)(4,4,5)(5,6,7),这以前发生过,我在for循环内打印了结果,这很好,但是当我在for循环外打印结果时,它给了我错误的结果。这是最终项目,它运行了,但我找不到我上面提到的问题:我只是用I和j复制了你的计算,但我想你可能对x和x有一些混淆也就是y。我会让你去做更正:)我想了想,但是之前,for循环中的计算是正确的,但是return语句中的计算是错误的,但是我会再次检查,谢谢你的帮助,这是一项艰巨的任务,因为这项挑战是在我的考试周期间提出的,所以我昨天和今天都没有时间从头开始学习scala,再次感谢
val R = Array.ofDim[Int](M1.length, M1(0).length)

for (i <- 0 to M1.length - 1; j <- 0 to M1(0).length - 1) {

  val tempList = List(Some(M1(i)(j)), calc(i - 1, j), calc(i, j - 1), calc(i + 1, j)).flatten
  R(i)(j) = math.ceil(tempList.sum.toDouble / tempList.length).toInt
}

def calc(i: Int, j: Int): Option[Int] = {

  if ((i < 0) || (j < 0) || (i > M1.length - 1))
    None

  else {

    Some(M1(i)(j))
  }
}
val R = for (i <- 0 to M1.length - 1) yield {
  for (j <- 0 to M1(0).length - 1) yield {

    val tempList = List(Some(M1(i)(j)), calc(i - 1, j), calc(i, j - 1), calc(i + 1, j)).flatten
    math.ceil(tempList.sum / tempList.length).toInt
  }
}
val R = (0 until M1.length).map { i =>
  (0 until M1(0).length).map { j =>

    val tempList = List(Some(M1(i)(j)), calc(i - 1, j), calc(i, j - 1), calc(i + 1, j)).flatten
    math.ceil(tempList.sum / tempList.length).toInt
  }
}
val R = (0 until M1.length).par.map { i =>
  (0 until M1(0).length).par.map { j =>

    val tempList = List(Some(M1(i)(j)), calc(i - 1, j), calc(i, j - 1), calc(i + 1, j)).flatten
    math.ceil(tempList.sum / tempList.length).toInt
  }.seq
}.seq