Scala用actor編寫簡單WordCount

package cn.allengao.actor

import java.io.File

import scala.actors.{Actor, Future}

//舊版本還是使用actors的actor,而不是使用akka的actor
import scala.collection.mutable
import scala.io.Source

class Task extends Actor {

  override def act(): Unit = {
    //希望程序線程池可以複用,效率會更高一些
    loop {
      react {
        //首先提交任務,告訴程序要執行的文件
        case SubmitTask(fileName) => {
          //getLines取出的是一個迭代器,可以實現從文件中取一些,讀一些的操作。進行局部彙總。
          val result = Source.fromFile(fileName).getLines().flatMap(_.split(" ")).map((_, 1)).toList.groupBy(_._1).mapValues(_.size)
          //把result的結果發送給case class ResultTask。
          sender ! ResultTask(result)
        }
        //如果任務執行完就停止
        case StopTask => {
          exit()
        }
      }
    }
  }
}

case class SubmitTask(fileName: String)

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

case object StopTask

object MyWordCount {
  def main(args: Array[String]) {
    val files = Array[String]("d://files//word1.txt", "d://files//word2.log")
    //用HashSet可變集合將replySet裝起來
    val replySet = new mutable.HashSet[Future[Any]]
    val resultList = new mutable.ListBuffer[ResultTask]

    //在這裏有多少個文件就new多少個actor
    for (f <- files) {
      val actor = new Task
      //使用異步發送消息,返回值是 Future[Any]
      val reply = actor.start() !! SubmitTask(f)
      replySet += reply
    }
    //通過while循環讀取replySet的內容,如果replySet.size=0,程序停止計算。
    while (replySet.size > 0) {
      //通過filter方法生成一個新的HashSet,裏面裝載的是任務完成的Future。
      val toCumpute = replySet.filter(_.isSet)
      for (r <- toCumpute) {
        //將結果取出來,相當於java中的get方法,取出來的是一個[Any]。
        val result = r.apply().asInstanceOf[ResultTask]
        resultList += result
        //將計算完的replaySet
        replySet -= r
      }
      //防止局部任務執行衝突,設置一個延遲
      Thread.sleep(100)
    }
    //彙總的功能
    //List(Map(),Map(),Map()),flat之後將Map()壓平,生成List((hello,5),(tom,2),(hello,2),(jerry,2))
    val finalResult = resultList.flatMap(_.result).groupBy(_._1).mapValues(_.foldLeft(0)(_ + _._2)).toList.sortBy(_._2).reverse
    println(finalResult)
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章