管道输入流被锁定
我正在尝试使用管道输入流写入数据。但从线程转储看来,管道输入流上有一个锁。
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
FileInputStream fis = null;
GZIPOutputStream gos = null;
byte[] buffer = new byte[1024];
try {
fis = new FileInputStream(file);
gos = new GZIPOutputStream(pos);
int length;
while ((length = fis.read(buffer, 0, 1024)) != -1)
gos.write(buffer, 0, length);
} catch(Exception e){
print("Could not read the file");
}
finally {
try {
fis.close();
gos.close();
}catch (Exception ie){
printException(ie);
}
}
writeObject(pis);
pos.close();
writeobj 方法将简单地从流中读取,但 read 方法被锁定。 线程转储表明管道输入流上有一些等待。
main" prio=10 tid=0x08066000 nid=0x48d2 in Object.wait() [0xb7fd2000..0xb7fd31e8]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0xa5c28be8> (a java.io.PipedInputStream)
at java.io.PipedInputStream.awaitSpace(PipedInputStream.java:257)
at java.io.PipedInputStream.receive(PipedInputStream.java:215)
- locked <0xa5c28be8> (a java.io.PipedInputStream)
at java.io.PipedOutputStream.write(PipedOutputStream.java:132)
at java.util.zip.GZIPOutputStream.finish(GZIPOutputStream.java:95)
at java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:146)
Locked ownable synchronizers:
- None
我不太确定是谁把它锁起来的。阅读文档以找出锁定调用。但无法弄清楚出了什么问题以及如何克服它。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 PipedInputStream 和 PipedOutputStream 必须在单独的线程中。
仔细阅读Javadoc:
http://docs.oracle.com/javase/6 /docs/api/java/io/PipedInputStream.html
Working with PipedInputStream and PipedOutputStream must be in separate threads.
Read the Javadoc carefully:
http://docs.oracle.com/javase/6/docs/api/java/io/PipedInputStream.html
PipedInputStream 有一个小的非扩展缓冲区。缓冲区已满后,写入 PipedOutputStream 块,直到由不同线程读取缓冲的输入。您不能在同一线程中使用两者,因为写入将等待不可能发生的读取。
在您的情况下,在写入所有数据之前,您不会读取任何数据,因此解决方案是使用 ByteArrayOutputStream 和 ByteArrayInputStream 相反:
PipedInputStream has a small non-expanding buffer. Once the buffer is full, writes to the PipedOutputStream block until the buffered input is read by a different thread. You cannot use the two from the same thread, because the write will be waiting for a read that cannot happen.
In your case, you are not reading any of the data until you have written all of it, so the solution is to use a ByteArrayOutputStream and ByteArrayInputStream instead:
我需要一个过滤器来拦截慢速连接,我需要尽快关闭数据库连接,所以我最初使用 Java 管道,但当仔细观察它们的实现时,它都是同步的,所以我最终使用一个小缓冲区和阻塞队列创建了自己的 QueueInputStream一旦缓冲区满了,就将缓冲区放入队列中,除非 LinkedBlockingQueue 使用锁定条件,否则它是无锁的,在小缓冲区的帮助下它应该很便宜,此类仅用于单个生产者和消费者每个实例:
I needed a filter to intercept slow connections where I need to close DB connections ASAP so I initially used Java pipes but when looked closer at their implementation, it is all synchronized so I ended up creating my own QueueInputStream using a small buffer and Blocking queue to put the buffer in the queue once was full, it is lock free except when for the lock conditions used at LinkedBlockingQueue which with the aid of the small buffer it should be cheap, this class is only intended to be used for a single producer and consumer per instance: