从scala actor检索对象
我有一个可以分配的密集任务,但其最终结果需要累积并传递给后续的另一个方法 具体来说,假设我正在对大量文本文件集合中的单个文件进行字数统计 到目前为止,我制定的版本如下所示:从scala actor检索对象,scala,actor,Scala,Actor,我有一个可以分配的密集任务,但其最终结果需要累积并传递给后续的另一个方法 具体来说,假设我正在对大量文本文件集合中的单个文件进行字数统计 到目前为止,我制定的版本如下所示: import scala.actors.Actor import scala.actors.Actor._ import scala.collection.mutable.{ArrayBuffer => mArray} case object Stop class Collector(val bin: mArray
import scala.actors.Actor
import scala.actors.Actor._
import scala.collection.mutable.{ArrayBuffer => mArray}
case object Stop
class Collector(val bin: mArray[(String, Int)], tcount: Int) extends Actor {
def act() {
loop {
receive {
case (fn: String, val: Int) => {
// the following "bin" object is what I ultimately need to get back
bin.append((fn, val))
}
case Stop => {
tcount -= 1
if(tcount == 0) exit()
}}}}}
class Processor(col: Collector, flist: Seq[File]) extends Actor {
def act() {
for(fn <- flist) {
val wcount = count words in fn // just a place holder for word counting code
col ! (fn, wcount)
}
col ! (id, Stop)
}
}
导入scala.actors.Actor
导入scala.actors.Actor_
导入scala.collection.mutable.{ArrayBuffer=>mArray}
案例对象停止
类收集器(val-bin:mArray[(String,Int)],tcount:Int)扩展了Actor{
def法案(){
环路{
接收{
大小写(fn:String,val:Int)=>{
//下面的“bin”对象是我最终需要返回的对象
附加仓位((fn,val))
}
案例停止=>{
t计数-=1
如果(tcount==0)退出()
}}}}}
类处理器(col:Collector,flist:Seq[File])扩展了Actor{
def法案(){
对于(fn使用actor,您不能“检索”任何内容,因为调用actor方法可能是危险的
相反,您可以让参与者发送答案。您可以为get
对象添加一个案例,或者在您的案例中,您可以让它将bin
发送到Stop处理程序中的某个地方。您可以使用!!
方法ping参与者以创建未来的结果。接收消息的参与者可以填写使用回复
获得结果
但是,通过使用执行器,您可以节省大量的管理工作,而执行器更适合于并行任务(在这里,您并没有真正的并发情况,因为参与者特别有用)
以下内容基于Scala 2.10(即将推出,您现在可以使用2.10.0-M6),因为它包含改进的并发框架:
import java.io.File
import concurrent._
import java.util.concurrent.Executors
// count words in a file - probably not the best possible way to write this
def wc(f: File): Int = io.Source.fromFile(f).getLines.map(
_.split(' ').filterNot(_ == "").size).sum
// utility method to get files within a directory (non-recursive!)
def filesInDir(dir: File): Seq[File] = dir.listFiles.toSeq.filter(_.isFile)
// process method which takes a list of files, spawns a word-count for each
// and collects the individual future results into a `Map` whose future is returned
def process(files: Seq[File])(implicit exec: ExecutionContext)
: Future[Seq[(File, Either[Throwable, Int])]] = {
val futs = files.map { f =>
// `future` submits the body for asynchronous processing. In order to
// gracefully handle IO errors, a successful result is wrapped in `Right`,
// and an exception in `Left`. The caller can decide how to handle errors.
future {
f -> (try {
Right(wc(f))
} catch {
case e: Throwable => Left(e)
})
}
}
// collect all the individual results into one result object.
// the new single `Future` is only complete after all of the individual futures
// have completed.
Future.sequence(futs)
}
例如:
// use as many threads as there are processor cores
val poolSize = sys.runtime.availableProcessors()
// create a new executor context to be used for spawning
implicit val exec = ExecutionContext.fromExecutor(
Executors.newFixedThreadPool(poolSize))
// call the process
val map = process(filesInDir(new File("/my/directory")))
// execute some body when the future is completed
map.onSuccess { case m =>
m foreach println
}
或者[Throwable,Int]
的替代方法是util。试试[Int]
,这也是Scala 2.10中的新功能。