Scala Concurrency with Futures

Future

注:下面内容参考Scala CookBook

Future: 在Akka中,Future是一个数据结构,用来检索并发操作的结果。这些操作通常是由Actor或者是Dispatcher直接执行。这些结果可以阻塞(同步),也可以不阻塞(异步)

你可能需要用一种简单的方式去并发的执行多个任务,包括当任务完成的时候对结果进行处理-Future

第一个例子表示了如何去创建一个future,阻塞并等待结果。

future为了执行callback和其它操作,需要ExecutionContext(执行环境),类似与java.util.concurrent.Executor

例子:

import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global  //导入"default golbal execution context"
//可以将execution context 作为一个线程池(Future并发需要)

object Future1 extends App{
  implicit val baseTime = System.currentTimeMillis()  //返回系统当前时间
  val f = Future {   //创建Future 仅仅让块中的代码去执行即可
    Thread.sleep(50)
    1 + 1
  }
  val result = Await.result(f,1 second)  //等待让Future返回,如果在时间内没有返回,就会报
  //java.util.concurrent.TimeoutException

  println(result)
  Thread.sleep(1000)
}

Run one thing,but don not block—use callback

一个更好的方法就是将future和callback方法一起使用,一共有3个callback方法:

onComplete   /    onSuccess     /   onFailure

onComplete

例子:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Random, Success}
object Future1 extends App{
  println("starting calculation ...")
  val f = Future {
    Thread.sleep(Random.nextInt(500))
    42
  }
  println("before onComplete")
  f.onComplete {
    case Success(value) => println(s"Got the callback, meaning = $value")
    case Failure(e) => e.printStackTrace
  }
  // do the rest of
  println("A ...");Thread.sleep(100)
  println("B ...");Thread.sleep(100)
  println("C ...");Thread.sleep(100)
  println("D ...");Thread.sleep(100)
  println("E ...");Thread.sleep(100)
  println("F ...");Thread.sleep(100)

}

每一次输出的结果Got the callback, meaning = $value在哪个位置都不一样,取决与Thread的睡眠时间。

控制台打印的结果表明:其它工作的代码工作的同时,future也可以进行工作

The onSuccess and Failure callback methods

如果你有时不想用onComplete,你可以使用onSuccess/onFailure

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Random
object Future1 extends App{
  val f = Future {
    Thread.sleep(Random.nextInt(500))
    val k = Random.nextInt(500)
    if (k > 100) throw new Exception("Yikes!" + k) else k
  }
  f onSuccess {
    case result => println(s"Success: $result")
  }
  f onFailure {
    case t => println(s"Exception: ${t.getMessage}")
  }
  // do the rest of
  println("A ...");Thread.sleep(100)
  println("B ...");Thread.sleep(100)
  println("C ...");Thread.sleep(100)
  println("D ...");Thread.sleep(100)
  println("E ...");Thread.sleep(100)
  println("F ...");Thread.sleep(100)
}
第一个Random决定控制台输出的位置

第二个Random决定输出的是onSuccess的内容还是onFailure的内容

这个例子类似于前面的onComplete例子


Creating a method return a Future[T]

定义一个方法异步计算返回Future,future中保留着结果

import scala.concurrent.{Await, Future, future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
object Futures2 extends App {
implicit val baseTime = System.currentTimeMillis
def longRunningComputation(i: Int): Future[Int] = future {
sleep(100)
i + 1
}     //方法返回的future中保留着数据
// this does not block
longRunningComputation(11).onComplete {
case Success(result) => println(s"result = $result")
case Failure(e) => e.printStackTrace
}
// keep the jvm from shutting down
sleep(1000)
}

Run multiple things; something depends on them; join them together

有时候你需要并发的执行几个操作,等待他们去完成,并对他们的结果进行聚合

import scala.concurrent.{Future,future}

import scala.concurrent.ExecutionContext.Implicits.global    类似与Thread pool,用于Future的并行操作

import scala.util.Random

object Cloud{

  def runAlgorithm(i:Int):Future[Int] = future {

    Thread.sleep(Random.nextInt(500))

    val result = i + 10

    println(s"returning result from cloud:$result")

    result

  }

}

object Future1 extends App{

  println("starting futures")

//下面三行并行处理

//result1 result2 result3均为Future[Int]类型

  val result1 = Cloud.runAlgorithm(10) 

  val result2 = Cloud.runAlgorithm(20)

  val result3 = Cloud.runAlgorithm(30) 

  println("before for-comprehension")

//当result1 result2 result3全部返回之后

  val result = for{

    r1 <- result1

    r2 <- result2

    r3 <- result3

  }yield (r1 + r2 + r3)

//返回的是Future,不能被直接打印,借助onSuccess

  println("before onSuccess")

  result onSuccess{

    case result => println(s"total = $result")

  }

  println("before sleep at the end")

  Thread.sleep(2000)  //睡眠等待Future返回onSuccess,如果不等待不会输出result的值

}

打印结果:

returning result from cloud:40
returning result from cloud:30
returning result from cloud:20

这三条是不确定的,所以这三条是并行的

total = 90

但是这一条是在最后,因为需要前面3个结果






















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值