Future
-
scala.concurrent.Future異步執行代碼塊import java.time._ import scala.concurrent._ import ExecutionContext.Implicits.global // 全域執行緒池 Future { Thread.sleep(10000) println(s"This is the future at ${LocalTime.now}") } println(s"This is the present at ${LocalTime.now}") -
監聽結果(阻塞)
import scala.concurrent.duration._ val f = Future { Thread.sleep(10000); 42 } val result = Await.result(f, 10.seconds) //阻塞10s val f = Future { ... } Await.ready(f, 10.seconds) val Some(t): Option[Try[T]] = f.value t match { case Success(v) => println(s"The answer is $v") case Failure(ex) => println(ex.getMessage) }
ready()
- 到達等待時間無結果時,會拋出例外
TimeoutException- 任務拋出的例外時,result() 會再次拋出例外, ready() 可獲取結果
-
回呼
val f = Future { Thread.sleep(10000) if (random() < 0.5) throw new Exception 42 } f.onComplete { case Success(v) => println(s"The answer is $v") case Failure(ex) => println(ex.getMessage) } -
問題:1.回呼地獄;2.執行順序無法預知
val future1 = Future { getData1() } val future2 = Future { getData2() } future1 onComplete { case Success(n1) => future2 onComplete { case Success(n2) => { val n = n1 + n2 println(s"Result: $n") } case Failure(ex) => ... } case Failure(ex) => ... }將 Future 看作集合
// val 會立即執行,def 呼叫時執行 val future1 = Future { getData1() } val future2 = Future { getData2() } // 都獲取到結果時,才會進行計算 val combined = for (n1 <- future1; n2 <- future2) yield n1 + n2 -
Promise
- 與 Java 8 中的
CompletableFuture類似 - Future 只讀,在任務完成時隱式設定結果值;Promise 類似,但結果值可顯式設定
// Future def computeAnswer(arg: String) = Future { val n = workHard(arg) n } // Promise def computeAnswer(arg: String) = { val p = Promise[Int]() Future { val n = workHard(arg) // 顯式設定結果 p.success(n) workOnSomethingElse() } // 立即回傳該 Promise 對應的 Future p.future } // 多個任務對應一個 Promise val p = Promise[Int]() Future { var n = workHard(arg) // 若 Promise 未完成則接受結果并回傳 true;否則忽略結果并回傳 false p.trySuccess(n) } Future { var n = workSmart(arg) p.trySuccess(n) }
- 與 Java 8 中的
-
執行背景關系
-
默認執行在全域的
fork-join執行緒池(默認大小為核數),適用于計算密集型任務 -
對于阻塞型/IO密集型的任務,可使用 Java 的
Executors// 隱式宣告,或者使用 Future.apply 顯式宣告 val pool = Executors.newCachedThreadPool() implicit val ec = ExecutionContext.fromExecutor(pool) val f = Future { val url = ... blocking { val contents = Source.fromURL(url).mkString ... } }
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/1984.html
標籤:Scala
上一篇:Scala XML
