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
如何在scala中同时执行此操作_Scala_Concurrency_Java.util.concurrent - Fatal编程技术网

如何在scala中同时执行此操作

如何在scala中同时执行此操作,scala,concurrency,java.util.concurrent,Scala,Concurrency,Java.util.concurrent,所以我有这段代码 dbs.foreach({ var map = scala.collection.mutable.Map[String, mutable.MutableList[String]]() db => val resultList = getTables(hive, db) map+=(db -> resultList) }) 它所做的是循环遍历一个数据库列表,对每个数据库执行一个在db中显示tables调用,然后将db->table添加到映射中

所以我有这段代码

dbs.foreach({
  var map = scala.collection.mutable.Map[String, mutable.MutableList[String]]()
  db =>
    val resultList = getTables(hive, db)
    map+=(db -> resultList)
})
它所做的是循环遍历一个数据库列表,对每个数据库执行一个
在db中显示tables
调用,然后将db->table添加到映射中。由于配置单元查询返回大约需要5秒的等待时间,如何同时执行此操作

更新代码--


您可以在任何Scala集合上使用
.par
并行执行下一次转换(使用默认并行,这取决于内核的数量)

此外,将
映射到一个(不可变的)映射而不是更新一个可变的映射更容易、更清晰

val result = dbs.par.map(db => db -> getTables(hive, db)).toMap

要对使用的并发线程数进行更多控制,请参见

您可以在任何Scala集合上使用
.par
并行执行下一次转换(使用默认并行,这取决于核心数)

此外,将
映射到一个(不可变的)映射而不是更新一个可变的映射更容易、更清晰

val result = dbs.par.map(db => db -> getTables(hive, db)).toMap
要对使用的并发线程数进行更多控制,请参见如果您想要更多控制(您希望等待多长时间,您希望使用多少线程,如果所有线程都很忙会发生什么,等等),您可以使用ThreadPollExecutor和Future

  implicit val context:ExecutionContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

  val dbs = List("db1", "db2", "db3")

  val futures = dbs.map {
   name => Future(name, getables(hive, name))
  }

  val result = Await.result( Future.sequence(futures), Duration(TIMEOUT, TimeUnit.MILLISECONDS) ).toMap
只要记住不要每次需要时都创建新的ExecutionContext,如果您想要更多的控制(您希望等待多长时间,您希望使用多少线程,如果所有线程都很忙会发生什么,等等),您可以使用ThreadPolludeExecutor和Future

  implicit val context:ExecutionContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

  val dbs = List("db1", "db2", "db3")

  val futures = dbs.map {
   name => Future(name, getables(hive, name))
  }

  val result = Await.result( Future.sequence(futures), Duration(TIMEOUT, TimeUnit.MILLISECONDS) ).toMap

记住不要每次需要时都创建一个新的ExecutionContext,不要使用vars和可变状态,尤其是在需要并发的情况下

 val result: Future[Map[String, Seq[String]] = Future
   .traverse(dbs) { name => 
       Future(name -> getTables(hive, name) )
   }.map(_.toMap)

不要使用vars和可变状态,尤其是在需要并发性的情况下

 val result: Future[Map[String, Seq[String]] = Future
   .traverse(dbs) { name => 
       Future(name -> getTables(hive, name) )
   }.map(_.toMap)

var映射=…
不应该在循环之外吗?请不要用答案代码更新您的问题。如果你发现一个答案与已经提交的答案完全不同,那么就把它作为一个答案发布。您可以回答自己的问题,即使您接受不同的答案。@jwvh这不是一个wser代码,而是另一个用户答复的示例代码。这不是回答代码吗?那更糟!从现在开始的一周/月/年后,寻求并发问题帮助的人会遇到这个问题,并看到标记为“仅更新”的代码,注意它非常类似于已接受的答案代码,并想知道,“这为什么适用于@testacc而不适用于我?”
var映射=…
不应该在循环之外吗?请不要用答案代码更新您的问题。如果你发现一个答案与已经提交的答案完全不同,那么就把它作为一个答案发布。您可以回答自己的问题,即使您接受不同的答案。@jwvh这不是一个wser代码,而是另一个用户答复的示例代码。这不是回答代码吗?那更糟!从现在开始的一周/月/年后,寻求并发问题帮助的人会遇到这个问题,并看到标记为“仅更新”的代码,注意它非常类似于已接受的答案代码,并想知道,“这为什么适用于@testacc而不适用于我?”这是解决问题的最佳方法“记住不要每次需要时都创建一个新的ExecutionContext”就是导入scala.concurrent.ExecutionContext.Implicits.global而不是创建一个;)我对这个代码块有一个问题。最后一次完成什么都会返回一个空值。
getables(hive,name)
返回一个字符串列表对象。无论最后一次完成的是什么,都会有一个空列表。是否有任何修复方法?使用我正在使用的确切代码块编辑我的帖子。这是随机发生的吗?完成所有未来需要多少时间?(我看到你用了10秒)它不相关,但请记住不要每次需要时都创建一个新的ExecutionContext。导入
scala.concurrent.ExecutionContext.Implicits.global
或在方法之外创建该val。@SebastianCelestino它随机发生,但总是发生。我制作了一个非常小的测试样本来使用。它有3个对象,每个对象返回futures,每个tak还有2秒就要完成了(只是一个sql调用)。不管最后一个要返回的对象是什么,都会返回空的。我尝试了20次future,同样的事情发生了,最终future返回空的。当所有执行都是竞争时,程序也不会结束,我的最后一行代码是println(“完成”)即使我将超时时间设置为
10秒
,我也尝试了更长和更短的超时时间,没有改变。@testacc我无法重现错误,下面是我代码的要点[程序未完成,因为线程池中存在非守护进程线程。您可以通过三种不同的方式解决此问题1)使用
scala.concurrent.ExecutionContext.Implicits.global
2)设置自定义线程工厂以创建守护进程线程3)关闭线程池最佳方式”记住不要每次需要时都创建一个新的ExecutionContext“就是导入scala.concurrent.ExecutionContext.Implicits.global,而不是创建一个;)我对这个代码块有一个问题。最后一次完成什么都会返回一个空值。
getables(hive,name)
返回一个字符串列表对象。无论最后一次完成的是什么,都会有一个空列表。是否有任何修复方法?使用我正在使用的确切代码块编辑我的帖子。这是随机发生的吗?完成所有未来需要多少时间?(我看到你用了10秒)它不相关,但请记住不要每次需要时都创建一个新的ExecutionContext。导入
scala.concurrent.ExecutionContext.Implicits.global
或在方法之外创建该val。@SebastianCelestino它随机发生,但总是发生。我制作了一个非常小的测试样本来使用。它有3个对象,每个对象返回futures,每个tak只需2秒即可完成(只需一个sql调用)