Scala-Actor简介并实现WordCount实例
一、为什么学习actor
scala actor 是scala 2.10.x 版本及以前版本的 Actor。
scala 在2.11.x 版本中将Akka加入。作为默认的Actor。老版本的Actor已经废弃。
学习actor为了学习AKKa做铺垫。
二、什么是Actor
Actor是消息并发模型。
scala中的Actor能够实现并行编程的强大功能。它是基于事件模型的并发机制。
scala是运用消息(message)的发送、接收来实现多线程的。
使用scala能够更容易的实现多线程应用开发。
三、Java并发编程与Scala Actor 并发编程的区别。
3.1 scala的Actor类似于Java中的多线程编程。但是不同的是,scala的Actor提供的模型与多线程有所不同。
3.2 scala的Actor尽可能的避免锁和共享状态。从而实现多线程并发时,资源征用的情况,进而提升多线程编程的性能。
3.3 sacal的模型还可以避免死锁等一系列传统多线程编程的问题。Java中多数使用的是可变状态的使用对象资源。对这些资源共享来实现多线程编程的话,控制好资源竞争与防止对象状态被意外修改是非常重要的。而对象状态不变形也是较难保证的。而在scala中我们可以通过复制不可变状态资源(即对象、scala中一切都是对象,方法、函数也是对象)的一个副本,再基于actor消息发送、接收机制进行并发编程。
四、Actor方法执行顺序
4.1 调用start()方法启动Actor
4.2 执行act()方法
4.3 向Actor发送消息
五、发送消息的方式
! --> 发送异步消息,没有返回值
!? -->发送同步消息,等待返回值。
!! -->发送异步消息,返回值是 Future[Any]
六、Actor简单举例功能实现
任务实现:
* 1,创建一个Actor
* 2,Actor的消息接收和发送。
* 3,用Actor并发编程实现WordCount
详细编程如下:
package day04
import scala.actors.Actor
/**
* 任务实现:
*
* 1,创建一个Actor
*/
class ActorDemo {
}
object ActorDemo01 extends Actor{
override def act(): Unit = {
for (i <- 1 to 10){
println("Actor01..."+i)
// Thread.sleep(1000)
}
}
}
object ActorDemo02 extends Actor{
override def act(): Unit = {
for (i <- 1 to 10){
println("Actor02..."+i)
// Thread.sleep(1000)
}
}
}
object ActorDemo{
def main(args: Array[String]): Unit = {
ActorDemo01.start()
ActorDemo02.start()
}
}
package day04
import scala.actors.Actor
/**
*
* 2,Actor的消息接收和发送。
*/
class ActorDemo001 extends Actor {
override def act(): Unit = {
while (true) {
//偏函数
receive {
case "start" => println("starting......")
case AsynMes(id, msg) => {
println(s"case id: $id,AsynMes: $msg")
Thread.sleep(2000)
sender ! ReplyMsg(5, "异步接收到了~~")
}
case SyncMsg(id, msg) => {
println(s"case id: $id,SyncMsg: $msg")
Thread.sleep(2000)
sender ! ReplyMsg(5, "同步接收到了~~")
}
}
}
}
}
object ActorDemo001 {
def main(args: Array[String]): Unit = {
/*
* 流程过程。
* 1,新建一个ActorDemo01并且进行启动。
* 2,给ActorDemo01发送一个没有返回值的异步消息。
*
*/
val actorDemo0 = new ActorDemo001
actorDemo0.start()
actorDemo0 ! AsynMes(12,"小伙子,我给你了异步")
println("AsynMes 异步消息没有返回值发送完成")
val resultSyncMsg:Any = actorDemo0 !? SyncMsg(13,"小伙子,我要给你有返回值的同步消息")
println("SyncMsg 同步消息有返回值发送完成")
println("resultSyncMsg 上面返回: "+ resultSyncMsg)
val resultAsynMes = actorDemo0 !! AsynMes(888, "小伙子,我给你发了异步,需要你的返回")
println("AsynMes 异步消息有返回值发送完成")
Thread.sleep(10000)
if(resultAsynMes.isSet){ //判断是否有值。若有值---
println("异步返回值: "+resultAsynMes.apply()) //resultAsynMes.apply() 取里面的值。
}else{
println("none")
}
//发送消息,没有返回值
}
}
case class AsynMes(id: Int, msg: String) //异步消息
case class SyncMsg(id: Int, msg: String) //同步消息
case class ReplyMsg(id: Int, msg: String)
package day04
import scala.actors.{Actor, Future}
import scala.collection.mutable.ListBuffer
import scala.io.Source
/**
* 3,用Actor并发编程实现WordCount
*/
class ActorWordCount {
}
object ActorWordCount {
def main(args: Array[String]): Unit = {
val replies: ListBuffer[Future[Any]] = new ListBuffer[Future[Any]]
//存放有值的Future 里的数据
val res: ListBuffer[Map[String, Int]] = new ListBuffer[Map[String,Int]]
//读取文件内容
val files: Array[String] = Array("C:\\Users\\Administrator\\Desktop\\Actor\\a.txt", "C:\\Users\\Administrator\\Desktop\\Actor\\a.txt", "C:\\Users\\Administrator\\Desktop\\Actor\\a.txt")
for (file <- files) {
/*
//同步操作。
val lines = Source.fromFile(file).getLines().toList
val wordsList:List[String] = lines.flatMap(_.split(" "))
val wordCount: Map[String, Int] = wordsList.map((_, 1)).groupBy(_._1).mapValues(_.size)
*/
//开启Actor后,接收file的数据
val actorFile = new ActorFile
actorFile.start()
val wordCount: Future[Any] = actorFile !! smTask(file)
//用ListBuffer集合进行接收数据
replies += wordCount
}
/*
验证数据集 replies 是否为空,并接收里面的数据
*/
while (replies.size > 0){
//获取不为空的listBuffer
val repliesRealy: ListBuffer[Future[Any]] = replies.filter(_.isSet)
for(repliesRealyOne <- repliesRealy){
res += repliesRealyOne.apply().asInstanceOf[Map[String,Int]]
replies -= repliesRealyOne
}
}
val wordCountResult: Map[String, Int] = res.flatten.groupBy(_._1).mapValues(_.foldLeft(0)(_+_._2))
println(wordCountResult)
}
}
class ActorFile extends Actor {
override def act(): Unit = {
while (true) {
receive({
case smTask(file) => {
val lines = Source.fromFile(file).getLines().toList
val wordsList: List[String] = lines.flatMap(_.split(" "))
val wordCount: Map[String, Int] = wordsList.map((_, 1)).groupBy(_._1).mapValues(_.size)
//异步发送数据,不要求有返回值
sender ! wordCount
}
})
}
}
}
case class smTask(file: String)
欢迎订阅关注公众号(JAVA和人工智能)
获取更多免费书籍、资源、视频资料 
文章超级链接: