Scala之Future

package base.day06.future

import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}

/**
  * @description FutureDriver
  * @author ZerlindaLi create at 2019/5/8 15:50
  * @version 1.0.0
  */
object FutureDriver {
  implicit val ec = ExecutionContext.global
  def main(args: Array[String]): Unit = {

    // 分别定义执行了3个线程f1,f2,f3
    val f1 = Future[Unit] {
      for (i <- 1 to 50) {
        println("f1:"+i)
      }
    }

    val f2 = Future{
      for (i <- 1 to 50) {
        println("f2:"+i)
      }
    }

    val f3 = Future{
      for (i <- 1 to 50) {
        println("f3:"+i)
      }
    }

    // 线程f4等f1,f2,f3执行完毕后之后,yield代码块里面的内容为f4线程执行的代码
    val f4 = for{
      list1 <- f1
      list2 <- f2
      list3 <- f3
    }yield{
      println(list1)
      println(list2)
      println(list3)
      for (i <- 1 to 50) {
        println("f4:"+i)
      }
    }

    // 回调,成功和失败两种结果
    f4.onComplete{
      case Success(e) => println("success")
      case Failure(t) => println("Failure")
    }

    println()
    println("f1 之後")

    // 主线程结束后,控制台会停掉,看不到子线程打印内容,所以这里沉睡10s.
    Thread.sleep(10000)
  }

}

以上为Scala的Future的基本用法,它还有函数组合的功能

    override def foreach[U](f: Nothing => U)(implicit executor: ExecutionContext): Unit = ()
    override def transform[S](s: Nothing => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] = this
    override def transform[S](f: Try[Nothing] => Try[S])(implicit executor: ExecutionContext): Future[S] = this
    override def transformWith[S](f: Try[Nothing] => Future[S])(implicit executor: ExecutionContext): Future[S] = this
    override def map[S](f: Nothing => S)(implicit executor: ExecutionContext): Future[S] = this
    override def flatMap[S](f: Nothing => Future[S])(implicit executor: ExecutionContext): Future[S] = this
    override def flatten[S](implicit ev: Nothing <:< Future[S]): Future[S] = this
    override def filter(p: Nothing => Boolean)(implicit executor: ExecutionContext): Future[Nothing] = this
    override def collect[S](pf: PartialFunction[Nothing, S])(implicit executor: ExecutionContext): Future[S] = this
    override def recover[U >: Nothing](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = this
    override def recoverWith[U >: Nothing](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = this
    override def zip[U](that: Future[U]): Future[(Nothing, U)] = this
    override def zipWith[U, R](that: Future[U])(f: (Nothing, U) => R)(implicit executor: ExecutionContext): Future[R] = this
    override def fallbackTo[U >: Nothing](that: Future[U]): Future[U] = this
    override def mapTo[S](implicit tag: ClassTag[S]): Future[S] = this
    override def andThen[U](pf: PartialFunction[Try[Nothing], U])(implicit executor: ExecutionContext): Future[Nothing] = this
Transforming Futures with map

map会等待原来的Future执行完毕,将原来的Future的结果进行操作,会返回一个新的Future
代码例子如下

    val fut = Future {
      Thread.sleep(3000);
      21 + 21
    }

    fut.map(x=>x+1).onComplete{
      case Success(s) => println("fut success:"+s)
      case Failure(e) => println("fut failure:"+e)
    }

这个的运行结果是

fut success:43

Transforming Futures with for expressions

for {}yeild{}是在for中将其他多个Future赋值,等待他们执行完毕之后,再执行yield这个新的Future.

    val fut1 = Future {
      Thread.sleep(1000);
      21 + 21
    }

    val fut2 = Future {
      Thread.sleep(1000);
      23 + 23
    }

    val res3 = for {
      x <- fut1
      y <- fut2
    } yield x + y

    res3.map(x=>x+1).onComplete{
      case Success(s) => println("res3 success:"+s)
      case Failure(e) => println("res3 failure:"+e)
    }

执行结果

res3 success:89

上面的代买在缩写一下…

    (for {
      x <- Future {
        Thread.sleep(1000);
        21 + 21
      }
      y <- Future {
        Thread.sleep(1000);
        21 + 21
      }
    } yield {x + y}).onComplete{
      case Success(s) => println("res4 success:"+s)
      case Failure(e) => println("res4 failure:"+e)
    }
Creating the Future: Future.failed, Future.successful, Future.fromTry, and Promises

我们在第一段代码中可以看到这样一句话

implicit val ec = ExecutionContext.global

这个是定义隐式的执行上下文来执行Future. 以下这些方式来创建Future不需要用到ExecutionContext

package base.day06.future

import scala.concurrent.Future
import scala.util.{Failure, Success}

object FutureConstructDriver {

  def main(args: Array[String]): Unit = {
    println(Future.successful { Thread.sleep(1000);21 + 21 })

    println(Future.failed(new Exception("Bummer!")))

    println(Future.fromTry(Success{21+21}))

    println(Future.fromTry(Failure(new Exception("Bummer!"))))
  }
}

执行结果如下

Future(Success(42))
Future(Failure(java.lang.Exception: Bummer!))
Future(Success(42))
Future(Failure(java.lang.Exception: Bummer!))

使用promise是最常见的创建Future的方式

    // 使用promise得到一个Future,这个Future由promise来控制。当promise完成时,这个future才会完成
    println("======= Promise[Int] ============")
    val pro = Promise[Int]
    val fut = pro.future
    println("pro:"+pro)
    println("fut:"+fut)

    // 通过success, failure, complete来完成promise.
    println("======= pro.success(42) ============")
    pro.success(42)
    println("pro : "+pro)
    println("fut : "+fut)

执行结果

======= Promise[Int] ============
pro:Future()
fut:Future()
======= pro.success(42) ============
pro : Future(Success(42))
fut : Future(Success(42))

Filtering: filter and collect

future提供了filter和collect两个过滤方法

参考文档

https://docs.scala-lang.org/zh-cn/overviews/core/futures.html#函数组合functional-composition和for解构for-comprehensions
《Programming in Scala, 3rd Edition》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zerlinda_Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值