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()}")//This is the present at 22:17:52.993//scala> This is the future at 22:18:02.994
在scala交互式可以看到效果,如果在idea中運行就看不到了
多個future併發執行,在scala交互式中,使用粘貼模式執行
Future {for(i <-1 to 100){print("A");Thread.sleep(10)}}
Future {for(i <-1 to 100){print("B");Thread.sleep(10)}}//得到的結果ABABABABABABABABABABABABABABABABABABBAABBAABABABABABBABBABABABABABAB
scala> val f = Future {Thread.sleep(5000);123}
f: scala.concurrent.Future[Int]=Future(<not completed>)//五秒之內的結果
scala> f
res8: scala.concurrent.Future[Int]=Future(<not completed>)//五秒之後的結果
scala> f
res9: scala.concurrent.Future[Int]=Future(Success(123))//另一個示例
scala> val f = Future {thrownewException("too late");123}
f: scala.concurrent.Future[Int]=Future(<not completed>)//失敗的示例
scala> f
res11: scala.concurrent.Future[Int]=Future(Failure(java.lang.Exception: too late))
import scala.util.{Failure, Success}//直接拋出異常,match語句會輸出異常的字符串haha,
val f2 = Future {thrownewException("haha");123}
Await.ready(f2,2.seconds)
val Some(t)= f2.value
t match{caseSuccess(v)=>println(s"The answer is ${v}")caseFailure(ex)=>println(ex.getMessage)}
import java.time._
import scala.util.Random
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
import scala.util.{Failure, Success, Try}
val f = Future{
Thread.sleep(10000)if(Random.nextInt()<5)thrownewException("haha")42}
f.onComplete{caseSuccess(v)=>println(s"The answer is ${v}")caseFailure(ex)=>println(ex.getMessage)}
組合future任務
組合兩個併發的future
val f1 = Future{Thread.sleep(10000);10}
val f2 = Future{Thread.sleep(5000);20}
val combined = f1.flatMap(n1 => f2.map(n2 => n1+n2))//或for
val combined1 =for(n1 <- f1 ; n2 <- f2 ) yield n1+n2
如果兩個有先後順序
將第二個的val改成def,這樣就會先執行第一個,再執行第二個
第一個是val或def並不重要,如果用def創建會在for開始的時候
def f1 = Future{Thread.sleep(10000);10}
def f2 = Future{Thread.sleep(5000);20}
val combined = f1.flatMap(n1 => f2.map(n2 => n1+n2))//或for
val combined1 =for(n1 <- f1 ; n2 <- f2 ) yield n1+n2
scala> val result = Future.sequence(futures)
result: scala.concurrent.Future[List[Int]]=Future(<not completed>)
scala> result
res3: scala.concurrent.Future[List[Int]]=Future(Success(List(30,10,20)))
traverse方法將map和sequence的兩步合併爲一步
第二個柯里化參數的函數會被應用到列表的每個元素
val futures =List(3,1,2).map(p => Future{ p*10})
val result = Future.sequence(futures)//合併爲
val result2 = Future.traverse(List(3,1,2))(p => Future{p *10})//result2: scala.concurrent.Future[List[Int]] = Future(<not completed>)//scala> result2//res5: scala.concurrent.Future[List[Int]] = Future(Success(List(30, 10, 20)))
def computerAnswer(arg:String)= Future{
val n =workHard(arg)
n
}
def computerAnswer2(arg:String)={
val p = Promise[Int]()
Future{
val n =workHard(arg)
p.success(n)workOnSomethingElse()}
p.future
}