首页 文章

未来要求Scala中的理解 - 我如何按顺序处理它们?

提问于
浏览
0

我有一个类似于这样的代码:

for (n <- 1 to 1000) {
  someFuture map {
    // some other stuff
}

这是一段基本代码,工作正常 . 但是, somefuture 对数据库进行了一些查询,并且数据库无法并行接收多个查询,这就是之前发生的事情(它产生了许多执行 somefuture 的线程,正如人们所期望的那样) .

理想情况下,我想按顺序执行(即当n = 1时调用 someFuture ,进行一些处理,当n = 2时调用 someFuture ,进行一些处理等) . 我想过使用一些阻塞方法(来自 Await ),但这发生在一个actor中,因此阻塞不是一个好主意 . 另一个想法是为这个特定的未来调用创建一个固定的线程池,但听起来有点矫枉过正 . 我该怎么做呢?

Update :我发现this answer建议按照我的想法创建一个固定的线程池 . 不过,这是正确的方法吗?

3 回答

  • 1

    您想要映射或平面化单个未来 .

    scala> val f = Future(42)
    f: scala.concurrent.Future[Int] = Future(Success(42))
    
    scala> (1 to 10).foldLeft(f)((f,x) => f.map(i => i + 1))
    res1: scala.concurrent.Future[Int] = Future(<not completed>)
    
    scala> res1
    res2: scala.concurrent.Future[Int] = Future(Success(52))
    
    scala> (1 to 10).foldLeft(f)((f,i) => {
         | println(i)
         | f.map(x => x+i) })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    res4: scala.concurrent.Future[Int] = Future(<not completed>)
    
    scala> res4
    res5: scala.concurrent.Future[Int] = Future(Success(97))
    
  • 0

    一种方法是将消息发送给处理数据的actor . 由于actor逐个处理消息,因此您将按顺序执行查询而不是并行执行 .

    for (n <- 1 to 1000) {
      someFuture map {
          x => actor ! x
        }
    }
    
  • 0

    理想的长期处理方法可能是使用连接池的数据库访问层 . 大多数框架,如游戏或光滑都有一些首选的处理方式,或者如果你想要独立的东西,DBCP可能是一个不错的选择 . 我认为大多数这些都应该有一种方法来限制连接数到固定大小,如果池中没有连接可以阻塞,这会限制你的并行性 .

    除了引入一些其他依赖,除了你提到的使用线程池执行上下文绝对是要走的路 . 这不是矫枉过正;这是非常常见的,并且比任何其他处理方式都要少得多 .

相关问题