当前位置: 首页 / 技术干货 / 正文
好程序员大数据培训分享Actor学习笔记

2020-06-04

大数据培训 好程序员

  好程序员大数据培训分享Actor学习笔记,在scala中她能实现很强大的功能,他是基于并发机制的一个事件模型

好程序员

  我们现在学的scala2.10.x版本就是之前的Actor

  同步:在主程序上排队执行的任务,只有前一个任务执行完毕后,才能执行下一个任务

  异步:指不进入主程序,而进入"任务对列"的任务,只有等主程序任务执行完毕,"任务对列"开始请求主程序,请求任务执行,该任务会进入主程序

  java

  共享变量 -- 加锁

  会出现锁死问题

  scala

  Actor不共享数据

  没有锁的概念

  Actor通信之间需要message(通信)

  Aactor执行顺序

  1.首先调用start()方法启动Actor

  2.调用start()方法后act()方法会被执行

  3.Actor之间进行发送消息

  Actor发送消息的三种方式

  ! -> 发送异步消息,没有返回值

  !? -> 发送同步消息,有返回值,会有线程等待

  !! -> 发送异步消息,有返回值,返回值类型Future[Any](用来获取异步操作结果)

  Actor并行执行

  //注意,这两个actor会并行执行,当其中一个for循环结束后,actor结束

  object ActorDemo01 {

  def main(args: Array[String]): Unit = {

  MyActor1.start()

  MyActor2.start()

  }

  }

  object MyActor1 extends Actor{

  override def act(): Unit = {

  for (i <- 1 to 10){

  println(s"actor => $i")

  Thread.sleep(2000)

  }

  }

  object MyActor2 extends Actor{

  override def act(): Unit = {

  for (i <- 1 to 5){

  println(s"actor2 => $i")

  Thread.sleep(2000)

  }

  }

  }

  }

  用Actor不断接受消息

  执行第一种方式,异步

  object ActorDemo02 {

  def main(args: Array[String]): Unit = {

  val actor: MyActor = new MyActor

  actor.start()

  //并行执行

  actor ! "start" // !->异步

  actor ! "stop"

  println("发送完成")

  }

  }

  class MyActor extends Actor{

  override def act(): Unit = {

  while (true){ //死循环

  receive { //接收

  case "start" => {

  println("starting")

  Thread.sleep(1000)

  println("started")

  }

  case "stop" => {

  println("stopping")

  Thread.sleep(1000)

  println("stopped")

  }

  }

  }

  }

  }

  第二种方式:利用react来代替receive,也就是说react线程可复用,比receive更高效

  object ActorDemo03 {

  def main(args: Array[String]): Unit = {

  val actor: MyActor3 = new MyActor3

  actor.start()

  actor ! "start"

  actor ! "stop"

  println("成功了")

  }

  }

  class MyActor3 extends Actor{

  override def act(): Unit = {

  loop {

  react{

  case "start" =>{

  println("starting")

  Thread.sleep(1000)

  println("sarted")

  }

  case "stop" =>{

  println("stoppting")

  Thread.sleep(1000)

  println("stopped")

  }

  }

  }

  }

  }

  结合样例类练习Actor发送消息

  //创建样例类

  case class AsyncMsg(id: Int, msg: String)

  case class SyncMsg(id: Int, msg: String)

  case class ReplyMsg(id: Int, msg: String)

  object ActorDemo01 extends Actor {

  override def act(): Unit = {

  while (true) {

  receive {

  case "start" => println("starting...")

  case AsyncMsg(id, msg) =>

  {

  println(s"id:$id,msg:$msg")

  sender ! ReplyMsg(1,"sucess") //接收到消息后返回响应消息

  }

  case SyncMsg(id,msg) => {

  println(s"id:$id,msg:$msg")

  sender ! ReplyMsg(2,"sucess")

  }

  }

  }

  }

  }

  object ActorTest{

  def main(args: Array[String]): Unit = {

  val actor: Actor = ActorDemo01.start()

  // //异步发送消息,没有返回值

  // actor ! AsyncMsg(3,"heihei")

  // println("异步消息发送完成,没有返回值")

  // //同步发送消息,有返回值

  // val text: Any = actor !? SyncMsg(4,"OK")

  // println(text)

  // println("同步消息发送成功")

  //异步发送消息,有返回值,返回类型为Future[Any]

  val reply: Future[Any] = actor !! SyncMsg(5,"OK is 不存在的")

  Thread.sleep(2000)

  if (reply.isSet){

  val applyMsg: Any = reply.apply()

  println(applyMsg)

  }else{

  println("Nothing")

  }

  }

  }

  Actor并行化的wordcount

  class Task extends Actor {

  override def act(): Unit = {

  loop {

  react {

  case SubmitTask(fileName) => {

  val contents = Source.fromFile(new File(fileName)).mkString

  val arr = contents.split("\r\n")

  val result = arr.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.length)

  //val result = arr.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.foldLeft(0)(_ + _._2))

  sender ! ResultTask(result)

  }

  case StopTask => {

  exit()

  }

  }

  }

  }

  }

  object WorkCount {

  def main(args: Array[String]) {

  val files = Array("c://words.txt", "c://words.log")

  val replaySet = new mutable.HashSet[Future[Any]]

  val resultList = new mutable.ListBuffer[ResultTask]

  for(f <- files) {

  val t = new Task

  val replay = t.start() !! SubmitTask(f)

  replaySet += replay

  }

  while(replaySet.size > 0){

  val toCumpute = replaySet.filter(_.isSet)

  for(r <- toCumpute){

  val result = r.apply()

  resultList += result.asInstanceOf[ResultTask]

  replaySet.remove(r)

  }

  Thread.sleep(100)

  }

  val finalResult = resultList.map(_.result).flatten.groupBy(_._1).mapValues(x => x.foldLeft(0)(_ + _._2))

  println(finalResult)

  }

  }

  case class SubmitTask(fileName: String)

  case object StopTask

  case class ResultTask(result: Map[String, Int])

好程序员公众号

  • · 剖析行业发展趋势
  • · 汇聚企业项目源码

好程序员开班动态

More+
  • HTML5大前端 <高端班>

    开班时间:2021-04-12(深圳)

    开班盛况

    开班时间:2021-05-17(北京)

    开班盛况
  • 大数据+人工智能 <高端班>

    开班时间:2021-03-22(杭州)

    开班盛况

    开班时间:2021-04-26(北京)

    开班盛况
  • JavaEE分布式开发 <高端班>

    开班时间:2021-05-10(北京)

    开班盛况

    开班时间:2021-02-22(北京)

    开班盛况
  • Python人工智能+数据分析 <高端班>

    开班时间:2021-07-12(北京)

    预约报名

    开班时间:2020-09-21(上海)

    开班盛况
  • 云计算开发 <高端班>

    开班时间:2021-07-12(北京)

    预约报名

    开班时间:2019-07-22(北京)

    开班盛况
IT培训IT培训
在线咨询
IT培训IT培训
试听
IT培训IT培训
入学教程
IT培训IT培训
立即报名
IT培训

Copyright 2011-2023 北京千锋互联科技有限公司 .All Right 京ICP备12003911号-5 京公网安备 11010802035720号