我有一个简单的方法,它将一行数据写入一个文件后跟一个异步执行的新行。
def writeToFile(bw: BufferedWriter, str: String) = {
bw.write(str)
bw.newLine
}
当我的程序运行时,我得到了混合"由于调用的异步性质,文件中的行。例如...说writeToFile(bw," foo")异步执行3次我可能得到:
正确输出
FOO
FOO
FOO
可能输出错误
foofoo
FOO
我可以通过使用 synchronized 方法来避免这种可能性:
def writeToFile(bw: BufferedWriter, str: String) = synchronized {
bw.write(str)
bw.newLine
}
根据我的研究,我无法确定如何安全"这是关于扩展我的应用程序。我可以使用 synchronized 找到的唯一示例是访问集合时,而不是写入文件。我的应用程序是在Play中构建的!框架2.4.2。
答案 0 :(得分:7)
我个人会为每个BufferedWriter创建一个akka actor,它将完全封装它。
import java.io.BufferedWriter
import akka.actor._
import playground.BufferedWriterActor.WriteToBuffer
object BufferedWriterActor {
val name = "BufferedWriterActor"
def props(bw: BufferedWriter) = Props(classOf[BufferedWriterActor], bw)
case class WriteToBuffer(str: String)
}
class BufferedWriterActor(bw: BufferedWriter) extends Actor {
def receive: Actor.Receive = {
case WriteToBuffer(str) =>
bw.write(str)
bw.newLine()
}
}
像这样使用:
import akka.actor.{ActorSystem, Props}
object HelloWorld {
def main(args: Array[String]): Unit = {
val system = ActorSystem("mySystem")
// Share this actor across all your threads.
val myActor = system.actorOf(BufferedWriterActor.props(bw), BufferedWriterActor.name)
// Send messages to this actor from all you threads.
myActor ! BufferedWriterActor.WriteToBuffer("The Text")
}
}
这将在一个线程中链接对此缓冲区的所有调用。
关于akka及其演员的更多信息在这里:
http://doc.akka.io/docs/akka/snapshot/scala/actors.html
播放框架本身也使用了akka,所以你应该可以使用它的默认ActorSystem,但是我不记得究竟是怎么回事。