【问题标题】:What is the best Scala thread-safe way to write to a BufferedWriter?写入 BufferedWriter 的最佳 Scala 线程安全方式是什么?
【发布时间】:2016-04-17 18:35:06
【问题描述】:

我有一个简单的方法,它将一行数据写入一个文件,然后是一个异步执行的新行。

  def writeToFile(bw: BufferedWriter, str: String) = {
    bw.write(str)
    bw.newLine
  }

当我的程序运行时,由于调用的异步性质,我在文件中“混淆”了行。例如...说 writeToFile(bw, "foo") 异步执行 3 次我可能会得到:

正确输出

富

富

富

可能输出不正确

foofoo

富

我可以通过使用这样的同步方法来避免这种可能性:

  def writeToFile(bw: BufferedWriter, str: String) = synchronized {
    bw.write(str)
    bw.newLine
  }

根据我的研究,我无法确定这在扩展我的应用程序方面有多“安全”。我可以找到使用 synchronized 的唯一示例是访问集合时,而不是写入文件。我的应用程序是在 Play 中构建的!框架 2.4.2。

【问题讨论】:

  • 你是对的,同步是 JVM 设计的锁定该函数调用的方式。但是,这并不意味着您传递的任何 BufferedWriter 在此期间都受到保护,如果您有其他线程试图使用它,因此包装和隐藏该对象可能是明智的。参考此链接了解更多信息:twitter.github.io/scala_school/concurrency.html

标签: multithreading scala playframework bufferedwriter playframework-2.4


【解决方案1】:

我个人会为每个 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://akka.io/

http://doc.akka.io/docs/akka/snapshot/scala/actors.html

另外play框架本身也使用akka,所以你应该可以使用它的默认ActorSystem,但是我不记得具体是怎么做的了,抱歉。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多