Scala 并发编程
并发编程是开发中及其重要的部分,本文用于说明 scala 中的并发编程。
Future
所谓 Future,是一种用于指代某个尚未就绪的值的对象。
Future 有两个状态:
- 待就位:等待结果
- 已就位:已经结束,可能接收到值或者发生异常
其中已就位也有两种情况:成功就位或发生异常。
Future 的一个重要属性在于它只能被赋值一次。一旦给定了某个值或某个异常,Future 对象就变成了不可变对象——无法再被改写。
创建 Future
最简单的创建 Future 的方法就是直接使用Future.apply()
方法。
假设我们使用某些流行的社交网络的假定 API 获取某个用户的朋友列表,我们将打开一个新对话(session),然后发送一个请求来获取某个特定用户的好友列表。
1 | import scala.concurrent._ |
监听结果
注册监听onComplete
方法可以在 Future 接收到结果的时候对其进行处理。
onComplete 会传递一个Try[T]
类型的值,它有2个子类:Success
或Failure
,成功时会回传Success
,失败时就是Failure
。
我们可以通过模式匹配来处理:
1 | f onComplete { |
函数组合
集合可用的map
,flatMap
等函数组合也可以使用在 Future 上。
这些组合操作方法可以帮助我们方便的转换 Future
1 | val f = Future { 1 }.map(v => s"$v").flatMap(v => Future { s"value = $v" }) |
for 解构
for
关键词也可以用于解构 Future,并且方便的转换其值。
1 | val future = for { |
recover
recover
通常和其它函数组合操作符一起使用,以避免发生异常之后直接结束。
1 | val purchase: Future[Int] = rateQuote map { |
此时如果map
的内容发生异常,会直接走到recover
里检查异常并返回值。
Promise
Promise 允许你在 Future 里放入一个值,不过只能做一次,Future 一旦完成,就不能更改了。
可以使用success
方法传入成功的值,或者failure
方法传入错误。
也可以使用complete
方法传入Try[T]
的子类,也就是Success[T]
或Failure
1 | val promise = Promise[String]() |
异步转同步
Await
Future 的onComplete
方法监听是异步的,我们也可以使用 Await 来阻塞当前线程获取 Future 的值
Await 会阻塞当前线程直到获取到值或者超时。
1 | def a = Future { Thread.sleep(2000); 100 } |
async/await
scala-async提供了类似 ES7 中提供的async/await
,使用它我们可以用同步非阻塞的方式写出异步代码
我们只需要用async
代替Future.apply
,然后用await
获取结果即可。
1 | val future = async { |
总结
Scala 中将异步操作抽象成 Future,通过其回调可以进行异步操作。使用scala-async可以将异步转成类似同步的写法,更易于阅读。