《快学Scala》第20章部分习题参考解答(Actor)
来源:互联网 发布:宝宝照片创意软件 编辑:程序博客网 时间:2024/06/06 22:25
注:本文所有的代码使用的使Akka的Actor框架,而没有使用Scala原生的Actor框架(deprecated)。
本文只做了前两题,actor编程还是很清晰的,我的框架可能不是最合理的,feel free to put your architect.
第一题
import CoordinatorActor.{CalRequest, CalRespond, StartCal}import akka.actor.{Actor, ActorSystem, Props}import scala.util.Randomobject CoordinatorActor{ def props(arr: Array[Int], n: Int): Props = Props(new CoordinatorActor(arr, n)) case object StartCal final case class CalRequest(arr: Array[Int], spos: Int, epos: Int) final case class CalRespond(ans: Long)}class CoordinatorActor(arr: Array[Int], n: Int) extends Actor{ val cal_cnt = 4 val interval = n / cal_cnt var sum:Long = 0l var respondCnt = 0 var tstamp1: Long = _ override def receive: Receive = { case StartCal => tstamp1 = System.currentTimeMillis() var last = 1 for(i <- 1 to (cal_cnt - 1)){ val calActor = context.actorOf(Props[CalActor], s"cal-$i") calActor ! CalRequest(arr, last, last + interval) last += (interval + 1) } val lastActor = context.actorOf(Props[CalActor], s"cal-$cal_cnt") lastActor ! CalRequest(arr, last, n) case CalRespond(partSum) => sum += partSum respondCnt += 1 if(respondCnt == cal_cnt){ println(s"[Actor] total: $sum, average: ${sum / n}") val tstamp2 = System.currentTimeMillis() println(s"[Actor] cost time: ${tstamp2 - tstamp1}ms") context.stop(self) } }}class CalActor extends Actor{ import CoordinatorActor._ override def receive: Receive = { case CalRequest(arr, spos, epos) => var sum: Long = 0l for(i <- spos to epos) sum += arr(i) sender() ! CalRespond(sum) }}object p1 extends App { val n = 10000000 val rand = Random val arr = new Array[Int](n + 10) for(i <- 1 to n) arr(i) = rand.nextInt(100) var sum1: Long = 0l val tstamp1 = System.currentTimeMillis() for(i <- 1 to n) sum1 += arr(i) println(s"total: $sum1, average: ${sum1 / n}") val tstamp2 = System.currentTimeMillis() println(s"cost time: ${tstamp2 - tstamp1}ms") val system = ActorSystem("average-cal") val coordinatorActor = system.actorOf(CoordinatorActor.props(arr, n), "cal-coordinator") coordinatorActor ! StartCal}
CalActor:执行计算任务
CoordinatorActor:执行调度管理任务,创建CalActor,执行结果统计。
执行结果:
n = 10000000
total: 495159047, average: 49cost time: 95ms[Actor] total: 495159047, average: 49[Actor] cost time: 51ms[INFO] [07/21/2017 16:51:27.273] [Thread-0] [CoordinatedShutdown(akka://average-cal)] Starting coordinated shutdown from JVM shutdown hookProcess finished with exit code 130 (interrupted by signal 2: SIGINT)
第二题
import java.awt.image.BufferedImageimport java.io.{File}import CoActor.{OpRespond, Start}import OperActor.StartOpimport akka.actor.{Actor, ActorLogging, ActorSystem, Props}// 执行者:执行像素操作object OperActor{ def props(img: BufferedImage, spos: Int, epos: Int, width: Int): Props = Props(new OperActor(img, spos, epos, width)) // 开始操作指令 case object StartOp}class OperActor(img: BufferedImage, spos: Int, epos: Int, width: Int) extends Actor with ActorLogging{ override def receive: Receive = { case StartOp => log.info(s"start operation between $spos and $epos") for(i <- spos to epos){ for(j <- 0 until width) { val ori = img.getRGB(j, i) img.setRGB(j, i, ~ori) } } // 向调度者报告完成 sender() ! OpRespond log.info(s"end operation between $spos and $epos") }}// 调度者:对执行者进行调度object CoActor{ def props(img: BufferedImage) : Props = Props(new CoActor((img))) // 开始调度指令 case object Start // 完成报告指令 case object OpRespond}class CoActor(img: BufferedImage) extends Actor with ActorLogging { val height = img.getHeight() val width = img.getWidth() val actor_cnt = 5 val interval = height / actor_cnt var response_cnt = 0 override def receive: Receive = { case Start => log.info("start operation") var last = 0 for(i <- 1 to (actor_cnt - 1)) { val opActor = context.actorOf(OperActor.props(img, last, last + interval, width)) last += (interval + 1) opActor ! StartOp } // 开始一个操作者 val lastActor = context.actorOf(OperActor.props(img, last, height - 1, width)) lastActor ! StartOp case OpRespond => response_cnt += 1 // 所有操作者全部完成任务,结束执行 if(response_cnt == actor_cnt){ log.info("end operation") val outFile = new File("resource/newImage.jpg") javax.imageio.ImageIO.write(img, "jpg", outFile) context.stop(self) } }}object p2 extends App {// println(System.getProperty("user.dir")) val image: BufferedImage = javax.imageio.ImageIO.read(new File("resource/image.jpg")) val system = ActorSystem("image-op") // 开始一个调度者 val coActor = system.actorOf(CoActor.props(image), "coordinator") coActor ! Start}
阅读全文
0 0
- 《快学Scala》第20章部分习题参考解答(Actor)
- 《快学Scala》16章习题参考解答(XML)
- 《快学Scala》第17章习题参考解答(类型参数)
- 《快学Scala》第18章习题参考解答(高级类型)
- 快学Scala学习笔记及习题解答(19-20解析与Actor)
- 快学Scala第20章----Actor
- 《快学Scala》第二章习题解答
- 《快学Scala》第三章习题解答
- 《快学Scala》第四章习题解答
- 《快学Scala》第五章习题解答
- 《快学Scala》第六章习题解答
- 《快学Scala》第九章习题解答
- 《快学Scala》第十三章习题解答
- 《快学Scala》第十六章习题解答
- 快学Scala习题解答—第五章 类
- 快学Scala习题解答—第六章 对象
- 快学Scala习题解答—第八章 继承
- 快学Scala习题解答—第十章 特质
- python+paramiko —— run cmd through middle host
- SQL Server执行计划相关知识
- 选择排序
- 你真的了解volatile吗?
- 动态添加SqlParameter
- 《快学Scala》第20章部分习题参考解答(Actor)
- SpringMVC第三篇【收集参数、字符串转日期、结果重定向、返回JSON】
- Clairewd’s message
- PLSQL 定义含有多个字段的数组类型变量
- 【POJ2125】Destroying The Graph(最小权覆盖点集)
- template模板使用规则 C++
- J
- 已解决:Execution failed for task Unable to delete directory:D:\VPRO\Vo\build\.....
- MYSQL 创建用户并授权