一.本章要点
- 每个actor都要扩展Actor类并提供act方法
- 要往actor发送消息,可以用actor!message
- 消息发送是异步的:”发完就忘“
- 要接受消息,actor可以调用receive或react,通常是在循环中这样做
- receive/react的参数是有case语句组成的代码块(偏函数)
- 不同actor之间不应该共享状态。总是使用消息来发送数据
- 不要直接调用actor的方法,通过消息进行通信
- 避免同步消息——将发送消息和等待响应分开
- 不同actor可以通过react而不是receive来共享线程,前提是消息处理器的控制流转足够简单
- 让actor挂掉是OK的,前提是你有其他actor监控着actor的生死。用链接来设置监控关系
二.创建和启动Actor
actor是扩展自Antor特质的类。该特质有一个抽象方法act。可以重写这个方法指定avtor的行为。act方法带有一个消息循环,例:
import scala.actors.Actor class HiActor extends Actor{ def act(){while(true){ receive{ case "Hi"=>println("Hello")} }} }
//调用start方法执行
val actor1=new HiActor
actor1.start()
act方法与Java中Runable接口中的run方法很相似,正如不同线程的run方法那样,不同actor的act方法也是并行运行的,对响应信息做了优化。
临时创建actor,利用Actor伴生对象的actor方法创建和启动actor:
import scala.actors.Actor._ val actor=actor{ while(true){ receive{case "Hi"=>println("Hello") } } }
三.发送消息
actor是一个处理异步消息的对象。
消息可以是任何对象。
使用!操作符发送小心,消息被发送当前线程继续执行——”发完就忘“(可以等待一个回复),一个好的做法是使用样例类作为消息,让actor使用模式匹配来处理消息。
四.接受消息
发送到actor的消息被存放在一个”邮箱“中,receive方法从邮箱获取下一条信息并将它传递给它的参数,该参数是一个偏函数。例:
receive { case Deposit(amount)=>.... case Withdraw(amount)=>... } //receive的参数是{case Deposit(amount)=>.... //case Withdraw(amount)=>... //}
该代码块被转换成一个类型为PartialFunction[Any,T]的对象,其中T是case语句=>操作符右边的表达式的计算结果的类型。这是个偏函数,因为它对那些能够匹配其中一个case语句的参数有定义。