- 概述
什么是Actor?
一个actor是一个容器,它包含 状态, 行为,信箱,子Actor 和 监管策略,所有这些包含在一个ActorReference(Actor引用)里。一个actor需要与外界隔离才能从actor模型中获益,所以actor是以actor引用的形式展现给外界的。
Scala的Actor类似于Java中的多线程编程。但是不同的是,Scala的Actor提供的模型与多线程有所不同。Scala的Actor尽可能地避免锁和共享状态,从而避免多线程并发时出现资源争用的情况,进而提升多线程编程的性能。
Scala Actor的这种模型还可以避免死锁等一系列传统多线程编程的问题。 Spark中使用的分布式多线程框架,是Akka。Akka也实现了类似Scala Actor的模型,其核心概念同样也是Actor
- Actor包引入
<!--scala actor-->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-actors</artifactId>
<version>2.10.5</version>
</dependency>
- actor单向通信
import scala.actors.Actor
/**
* 学习scala actor的基本操作
* 和java中的Runnable Thread几乎一致
*
* 第一步:编写一个类,扩展特质trait Actor(scala 的actor)
* 第二步:复写其中的act方法
* 第三步:创建该actor的对象,调用该对象的start()方法,启动该线程
* 第四步:通过scala的操作符"!",发送消息
* 第五步:结束的话,调用close即可
*
* 模拟单向打招呼
*/
object ActorOps {
def main(args: Array[String]): Unit = {
val mFActor = new MyFirstActor()
mFActor.start()
// 发送消息
mFActor ! "小明,代码写完了吗?"
mFActor ! "马上快实现好功能了~"
mFActor ! "加油"
}
}
class MyFirstActor extends Actor {
override def act(): Unit = {
while(true) {
receive {
case str: String => println(str)
}
}
}
}
运行打印结果:
小明,代码写完了吗?
马上快实现好功能了~
加油
- 使用(case class)进行actor消息传递
测试代码如下:
import scala.actors.Actor
/**
*
*/
object GreetingActor {
def main(args: Array[String]): Unit = {
val ga = new GreetingActor
ga.start()
ga ! Greeting("小明")
ga ! WorkContent("做项目了")
}
}
case class Greeting(name:String)
case class WorkContent(content:String)
class GreetingActor extends Actor {
override def act(): Unit = {
while(true) {
receive {
case Greeting(name) => println(s"Hello, $name")
case WorkContent(content) => println(s"Let's talk about sth. with $content")
}
}
}
}
运行输出结果:
Hello, 小明
Let's talk about sth. with 做项目了
- actor相互通信
实现代码:
import scala.actors.Actor
/**
* actor之线程间,互相通信
*
* studentActor
* 向老师问了一个问题
*
* teacherActor
* 向学生做回应
*
* 通信的协议:
* 请求,使用Request(内容)来表示
* 响应,使用Response(内容)来表示
*/
object _03CommunicationActorOps {
def main(args: Array[String]): Unit = {
val teacherActor = new TeacherActor()
teacherActor.start()
val studentActor = new StudentActor(teacherActor)
studentActor.start()
studentActor ! Request("小明啊,scala学习为什么这么难啊")
}
}
case class Request(req:String)
case class Response(resp:String)
class StudentActor(teacherActor: TeacherActor) extends Actor {
override def act(): Unit = {
while(true) {
receive {
case Request(req) => {
// 向老师请求相关的问题
println("学生向老师说:" + req)
teacherActor ! Request(req)
}
case Response(resp) => {
println(resp)
println("高!")
}
}
}
}
}
class TeacherActor() extends Actor {
override def act(): Unit = {
while (true) {
receive {
case Request(req) => { // 接收到学生的请求
sender ! Response("这个问题,需要如此搞定~")
}
}
}
}
}
输出结果如下:
学生向老师说:小明啊,scala学习为什么这么难啊
这个问题,需要如此搞定~
高!
- 同步消息和Future
1 // 默认情况下,消息都是异步的;但是如果希望发送的消息是同步的,即对方接受后,一定要给自己返回结果,那么可以使用!?的方式发送消息。即val reply = actor !? message。
2 // 如果要异步发送一个消息,但是在后续要获得消息的返回值,那么可以使用Future。即!!语法。val future = actor !! message。val reply = future()。