簡體   English   中英

在 Future.sequence 的成功上的片狀

[英]Flaky onSuccess of Future.sequence

我寫了這個方法:

import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }
}

我期待 Future.sequence 將 List[Future] 收集到 Future[List] 中,然后等待每個期貨(在我的情況下為 f1 和 f2)完成,然后在我的情況下對 Future[List] seq 調用 onSuccess。

但是在多次運行此代碼后,它只會偶爾打印一次“List(1, 2)”,我無法弄清楚為什么它沒有按預期工作。

試試這個,

import scala.concurrent._
import java.util.concurrent.Executors
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  implicit val exec = ExecutionContext.fromExecutor(Executors.newCachedThreadPool)
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }
}

這將始終打印List(1,2) 原因很簡單,上面的exec是一個線程(不是守護線程)的 ExecutionContext ,在您的示例中, ExecutionContext 是從ExecutionContext.Implicits.global隱式獲取的默認值,其中包含守護線程。

因此,作為守護進程,進程不會等待seq未來完成並終止。 如果seq確實完成了,那么它就會打印出來。 但這並不總是發生

應用程序在未來完成之前退出。

你需要阻塞直到未來完成 這可以通過多種方式實現,包括更改 ExecutionContext、實例化新的 ThreadPool、Thread.sleep 等,或使用scala.concurrent.Await方法

代碼最簡單的方法是使用Await.ready 這會在指定的時間內阻止future 在下面修改后的代碼中,應用程序在退出前等待 5 秒。

還要注意,額外的 import scala.concurrent.duration以便我們可以指定等待的時間。

import scala.concurrent._
import scala.concurrent.duration._
import java.util.concurrent.Executors
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }

  Await.ready(seq, 5 seconds)
}

通過使用Await.result ,您也可以跳過onSuccess方法,因為它會將結果列表返回給您。

例子:

val seq: List[Int] = Await.result(Future.sequence(lf), 5 seconds)
println(seq)

暫無
暫無

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

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