此Scala代码无限期挂起
import java.io._
import scala.io.Source
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
def copy(inputStream: InputStream, outputStream: OutputStream): Unit = {
val buffer = new Array[Byte](1024)
var bytesRead = inputStream.read(buffer)
while (bytesRead != -1) {
outputStream.write(buffer, 0, bytesRead)
bytesRead = inputStream.read(buffer)
}
outputStream.flush()
}
val os0 = new PipedOutputStream
val is0 = new PipedInputStream(os0)
val os1 = new PipedOutputStream
val is1 = new PipedInputStream(os1)
// write to os0
Future {
os0.write(("foobarbaz"*1000).getBytes("utf-8"))
os0.close()
}
// copy is0 to os1
Future {
copy(is0, os1)
os1.close()
}
// read is1 to output
val result = Source.fromInputStream(is1).mkString
println(result)
但是如果我修改输入数据使其小于1024B缓冲区大小PipedInputStream
,则它可以工作,即
os0.write(("foobarbaz").getBytes("utf-8"))
它成功地打印
> foobarbaz
这里发生了什么?管道流实现中是否存在死锁?
Scastie链接:https://scastie.scala-lang.org/131qJRP9Sc6wSVXrqODd2A
1条答案
按热度按时间46scxncf1#
PipedInputStream/PipedOutputStream组合用于多线程操作,其中读取器和写入器在不同的线程中使用。PipedOutputStream上的写入操作将在缓冲区已满时阻塞,因此它不适用于单线程操作,如复制方法。
您可以只使用StringWriter来缓冲输出以供以后使用。