在我的scala代码中,我正在从我的main函数创建一个GzipOutputStream对象,并在将来使用它,在每个循环中调用它。在迭代开始未来之前,等待上一次迭代的未来。因此,GzipOutputStream对象永远不会被不同的线程同时访问。但是,我注意到该程序有时会生成损坏的zip文件。所以,我的问题是,如果不同时使用不同线程的GzipOutputStream对象是否安全?
基本上,以下是pseducode
gzos = new GzipOutputStream(...)
....
for loop:
f = future(futureFunction)
....
waitFor(f)
gzos.close
def futureFunction(...)
...
gzos.write(...)
...
答案 0 :(得分:2)
GzipOutputStream
是一个有状态对象。仅仅一个接一个地运行任务是不够的。对于正确的工作,您需要第一次迭代所做的更改对执行第二次迭代的线程可见。
基本上你需要第一次迭代的关系结束'发生在第二次迭代开始之前#。
我不确定这种关系是否适用于任意执行上下文。 但是,如果你使用例如单线程执行上下文,那显然是正确的。
答案 1 :(得分:0)
你可能会发现akka-stream非常适合这个问题。
import akka.stream.scaladsl._
import akka.stream._
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
val runnable: Future[IOResult] =
Source(1 to 10)
.mapAsync(1)(i => Future.successful(i))
.map(s => ByteString(s + "\n"))
.via(Compression.gzip)
.runWith(FileIO.toPath(Paths.get("out.gz")))
val result = Await.result(runnable, 10.seconds)
了解更多信息,请参阅http://doc.akka.io/docs/akka/2.5/scala/stream/stream-quickstart.html