我正在尝试编写一个简单的生成器类,以便学习Actors。我希望有一个生产者,它以某个目录开头,由File对象表示,然后将消息发送给其他actor以处理这些文件。最初,我正在阅读文件的内容,但是,为了简单起见,现在我只是收集它们的路径。 再一次,这没有真正的世界价值,但它对我有实际价值,因为我认为这将使我更好地理解演员。这是我到目前为止所做的:
import java.io._
import java.util.concurrent._
import scala.actors.Actor
import scala.io.Source
import java.util.concurrent.locks.ReentrantLock
import java.util.concurrent.atomic.AtomicLong
case class FileSystemObject(path:File)
case class FileContent(content:String)
case object Stop
case object Processed
class ResultAcumulator extends Actor {
var results:List[String] = Nil
var finished = false
def act() = {
loop {
react {
case FileContent(content) => {
results ::= content
}
case Stop => {
finished = true;
exit
}
}
}
}
}
class FileSystemReader(accumulator:Actor) extends Actor {
def act() = {
loop {
react {
case FileSystemObject(path) => {
if(path.isFile) {
accumulator ! FileContent(path.toString)
sender ! Processed
}
}
case Stop => exit
}
}
}
}
class FileSystemProducer(start:File,acumulator:Actor,reader:Actor) extends Actor {
var totalFilesProcessed = 0
def act() = {
val files = start.listFiles
files.foreach{ f =>
(reader ! FileSystemObject(f))
}
loop {
react {
case Processed => {
totalFilesProcessed += 1
if(totalFilesProcessed == files.length) {
reader ! Stop
acumulator ! Stop
Xo.decrementLatch
}
}
}
}
}
}
object Xo {
var latch = new CountDownLatch(1)
def decrementLatch = latch.countDown
def main(args : Array[String]) = {
val acumulator = new ResultAcumulator
val fsReader = new FileSystemReader(acumulator)
val producer = new FileSystemProducer(new File("d:/rails/a"),acumulator,fsReader)
acumulator.start
fsReader.start
producer.start
latch.await
acumulator.results.foreach(println)
}
}
现在处于状态,它会永远运行,我看不到输出。啊,还有一件事。在程序退出之前,我希望它列出“已处理”的结果。我搜索了一下,找到了CountDownLatch类。我想用循环/反应而不是while / receive来实现这个。我很确定问题是由于我有以下这些问题引起的:
files.foreach{ f =>
(reader ! FileSystemObject(f))
}
并且我的反应循环稍低,但我不知道如何修复它。
答案 0 :(得分:3)
我猜相关部分是
case FileSystemObject(path)=> {
if(path.isFile){
累加器! FileContent(path.toString)
发件人!处理
}
}
这里不是“普通文件”的东西,例如目录,不会被发送到累加器。
因此,如果“d:/ rails / a”中存在子目录,则测试totalFilesProcessed == files.length
将始终失败。