我有两个线程。其中一个写入PipedOutputStream,另一个从相应的PipedInputStream读取。背景是一个线程正在从远程服务器下载一些数据,并通过管道流将其多路复用到其他几个线程。

问题是有时(尤其是在下载大(> 50Mb)文件时),我得到 java.io.IOException:尝试从PipedInputStream读取时,管道断开了
Javadoc说A pipe is said to be broken if a thread that was providing data bytes to the connected piped output stream is no longer alive.的确,我的写入线程在将所有数据写入PipedOutputStream之后确实死了。

有什么办法吗?如何防止PipedInputStream抛出此异常?我希望能够读取所有写入PipedOutputStream的数据,即使编写线程完成了他的工作。 (如果有人知道如何保持 Activity 状态,直到将读取所有数据,此解决方案也是可以接受的)。

最佳答案

使用java.util.concurrent.CountDownLatch,并且不要在第二个线程发出已完成从管道读取的信号之前结束第一个线程。

更新:快速而肮脏的代码,以在下面说明我的评论

    final PipedInputStream pin = getInputStream();
    final PipedOutputStream pout = getOutputStream();

    final CountDownLatch latch = new CountDownLatch(1);

    InputStream in = new InputStream() {

        @Override
        public int read() throws IOException {
            return pin.read();
        }

        @Override
        public void close() throws IOException {
            super.close();
            latch.countDown();
        }
    };


    OutputStream out = new OutputStream(){

        @Override
        public void write(int b) throws IOException {
            pout.write(b);
        }

        @Override
        public void close() throws IOException {
            while(latch.getCount()!=0) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    //too bad
                }
            }
            super.close();
        }
    };

    //give the streams to your threads, they don't know a latch ever existed
    threadOne.feed(in);
    threadTwo.feed(out);

07-28 08:25