使用从另一个线程创建的Outputstream是否安全?

时间:2017-05-16 08:33:13

标签: java multithreading scala

在我的scala代码中,我正在从我的main函数创建一个GzipOutputStream对象,并在将来使用它,在每个循环中调用它。在迭代开始未来之前,等待上一次迭代的未来。因此,GzipOutputStream对象永远不会被不同的线程同时访问。但是,我注意到该程序有时会生成损坏的zip文件。所以,我的问题是,如果不同时使用不同线程的GzipOutputStream对象是否安全?

基本上,以下是pseducode

gzos = new GzipOutputStream(...)
....
for loop:
  f = future(futureFunction)
  ....
  waitFor(f)
gzos.close

def futureFunction(...)
  ...
  gzos.write(...)
  ...

2 个答案:

答案 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