在写入时从ByteArrayOutputStream读取

时间:2017-10-09 02:29:43

标签: java multithreading inputstream bytearrayoutputstream

我有一个不断生成数据并在其自己的线程上将其写入ByteArrayOutputStream的类。我有一个第二个线程获取对此ByteArrayOutputStream的引用。我希望第二个线程读取ByteArrayOutputStream的任何数据(并清空),然后在它没有得到任何字节和睡眠时停止。在睡眠之后,我希望它尝试获取更多数据并再次清空它。

我在网上看到的例子说使用PipedOutputStream。如果我的第一个线程是从一个单独的可重用库使外部世界可以使用ByteArrayOutputStream,我就不知道如何将inputStream连接到它。

如何设置PipedInputStream将其连接到ByteArrayOutputStream以从上面读取它?另外,当从ByteArrayOutputStream读取最后一个块时,我是否会看到bytesRead == -1,指示outputStream何时从第一个线程关闭?

非常感谢, 麦克

1 个答案:

答案 0 :(得分:3)

直接写入PipedOutputStream(也就是说,根本不要使用ByteArrayOutputStream)。它们都扩展OutputStream,因此具有相同的接口。

connectPipedOutputStream中的PipedInputStream方法用于将两个管道连接在一起,或者您可以使用其中一个构造函数来创建一对。

PipedOutputStream中的缓冲区填满时,PipedInputStream的写入将被阻塞,当缓冲区为空时,PipedInputStream的读取将阻塞,因此生产者线程将会休眠(阻止)如果它“超前”消费者,反之亦然。

在重新检查缓冲区之前阻塞线程等待1000ms后,最好在写入完成后刷新输出(这会在读取器休眠时唤醒它)。

当您关闭生产者线程中的输出流时,您的输入流将看到EOF(bytesRead == -1)。

import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PipeTest {
    public static void main(String[] args) throws IOException {
        PipedOutputStream out = new PipedOutputStream();
        // Wire an input stream to the output stream, and use a buffer of 2048 bytes
        PipedInputStream in = new PipedInputStream(out, 2048);

        ExecutorService executor = Executors.newCachedThreadPool();

        // Producer thread.
        executor.execute(() -> {
            try {
                for (int i = 0; i < 10240; i++) {
                    out.write(0);
                    // flush to wake the reader
                    out.flush();
                }
                out.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        });

        // Consumer thread.
        executor.execute(() -> {
            try {
                int b, read = 0;
                while ((b = in.read()) != -1) {
                    read++;
                }
                System.out.println("Read " + read + " bytes.");
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        });

        executor.shutdown();
    }
}