设为首页 加入收藏

TOP

Scalaz(44)- concurrency :scalaz Future,尚不完整的多线程类型(一)
2017-10-10 12:12:10 】 浏览:5775
Tags:Scalaz concurrency scalaz Future 尚不 完整 线程 类型

scala已经配备了自身的Future类。我们先举个例子来了解scala Future的具体操作: 

 1 import scala.concurrent._  2 import ExecutionContext.Implicits.global
 3 object scalafuture {  4   def dbl(i: Int): Future[Int] = Future { Thread.sleep(1000) ; i + i }  5                                       //> dbl: (i: Int)scala.concurrent.Future[Int]
 6   val fdbl = dbl(3)                   //> fdbl : scala.concurrent.Future[Int] = List()
 7  fdbl.onSuccess {  8     case a => println(s"${a/2} + ${a/2} = $a")  9  } 10   println("calculating ...")          //> calculating ...
11   Thread.sleep(2000)                  //> 3 + 3 = 6
12 }

 这是一个标准的异步运算;在成功完成运算事件上绑定callback来获取在其它线程中的运算结果。我们也可以进行异常处理:

1   val fdz = Future { 3 / 0 }      //> fdz : scala.concurrent.Future[Int] = List()
2  fdz.onFailure { 3     case e => println(s"error message {${e.getMessage}}") 4  } 5   Thread.sleep(100)               //> error message {/ by zero}

又或者同时绑定运算成功和失败事件的callback函数:

1  import scala.util.{Success, Failure} 2  fdz onComplete { 3     case Success(a) => println(s"${a/2} + ${a/2} = $a") 4     case Failure(e) => println(s"error message {${e.getMessage}}") 5  } 6   Thread.sleep(100)               //> error message {/ by zero}

 scala Future 实现了flatMap,我们可以把几个Future组合起来用:

 1   def dbl(i: Int): Future[Int] = Future { Thread.sleep(1000); i + i }  2                                                   //> dbl: (i: Int)scala.concurrent.Future[Int]
 3   def sqr(i: Int): Future[Int] = Future { i * i } //> sqr: (i: Int)scala.concurrent.Future[Int]
 4   def sum(a: Int, b: Int): Future[Int] = Future { a + b }  5                                           //> sum: (a: Int, b: Int)scala.concurrent.Future[Int]
 6   val fsum = for {  7     a <- dbl(3)  8     b <- sqr(a)  9     c <- sum(a,b) 10   } yield c                               //> fsum : scala.concurrent.Future[Int] = List()
11   
12   fsum onSuccess { case c => println(s"the combined result is: $c") } 13   Thread.sleep(2000)                     //> the combined result is: 42

scala Future利用flatMap实现了流程运算:先运算dbl再sqr再sum,这个顺序是固定的即使它们可能在不同的线程里运算,因为sqr依赖dbl的结果,而sum又依赖dbl和sqr的结果。

好了,既然scala Future的功能已经比较完善了,那么scalaz的Future又有什么不同的特点呢?首先,细心一点可以发现scala Future是即时运算的,从下面的例子里可以看出:

1  import scala.concurrent.duration._ 2   val fs = Future {println("run now..."); System.currentTimeMillis() } 3                                          //> run now... 4                                          //| fs : scala.concurrent.Future[Long] = List()
5   Await.result(fs, 1.second)             //> res0: Long = 1465907784714
6   Thread.sleep(1000) 7   Await.result(fs, 1.second)             //> res1: Long = 1465907784714

可以看到fs是在Future构建时即时运算的,而且只会运算一次。如果scala Future中包括了能产生副作用的代码,在构建时就会立即产生副作用。所以我们是无法使用scala Future来编写纯函数的,那么在scalaz里就必须为并发编程提供一个与scala Future具同等功能但又不会立即产生副作用的类型了,这就是scalaz版本的Future。我们看看scalaz是如何定义Future的:scalaz.concurrent/Future.scala

sealed abstract class Future[+A] { ... object Future { case class Now[+A](a: A) extends Future[A] case class Async[+A](onFinish: (A => Trampoline[Unit]) => Unit) extends Future[A] case class Suspend[+A](thunk: () => Future[A]) extends Future[A] case class BindSuspend[A,B](thunk: () => Future[A], f: A => Future[B]) extends Future[B] case class BindAsync[A,B](onFinish: (A => Trampoline[Unit]) => Unit, f: A => Future[B]) extends Future[B] ...

Future[A]就是个Free Monad。它的结构化表达方式分别有Now,Async,Suspend,BindSuspend,BindAsync。我们可以用这些结构实现flatMap函数,所以Future就是Free Monad:

 

  def flatMap[B](f: A => Future[B]): Future[B] = this match { case Now(a) => Suspend(() => f(a)) case Suspend(thunk) => BindSuspend(thunk, f) case Async(listen) => BindAsync(listen, f) cas
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇scala学习手记10 - 访问修饰符 下一篇Scalaz(45)- concurrency :Ta..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目