pipedinputstream 和 pipedoutputstream 提供同一 jvm 内两线程间单向、阻塞式、基于字节的管道通信,需显式 connect() 绑定,写满/读空时自动阻塞,缓冲区默认 1024 字节,不支持跨进程或双向通信。

Java 中的 PipedInputStream 和 PipedOutputStream 可以在两个线程间建立**单向、阻塞式、基于字节的通信管道**,无需网络或文件系统参与,适合轻量级线程协作(如生产者-消费者模型)。关键在于:二者必须配对使用,且需在连接前完成绑定(或通过构造函数自动连接)。
核心步骤:创建并连接管道流
最安全的方式是显式调用 connect(),避免因初始化顺序导致的 IOException(如“Pipe not connected”):
- 先创建
PipedInputStream和PipedOutputStream实例 - 立即调用
pipedReader.connect(pipeWriter)(注意方向:输入流连接输出流) - 确保连接发生在任何读/写操作之前
典型生产者-消费者线程结构
一个线程写入 PipedOutputStream,另一个从 PipedInputStream 读取。读写操作会自动同步——写满缓冲区时写线程阻塞,读空时读线程阻塞:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 生产者线程:获取
PipedOutputStream,调用write(byte[])或write(int) - 消费者线程:从
PipedInputStream调用read(byte[])或read() - 缓冲区默认大小为 1024 字节,可通过构造函数指定,如
new PipedInputStream(8192)
重要注意事项与常见陷阱
该机制不是万能的,需规避几个典型问题:
- 不能跨 JVM 或进程使用:仅限同一 JVM 内的线程间通信
- 不支持双向通信:一对管道只能单向传输;双向需两套管道(A→B + B→A)
-
异常处理必须严谨:若写端提前关闭,读端
read()返回 -1;若写端抛异常未关闭,读端会一直阻塞 - 避免死锁:不要在同一线程中既读又写同一对管道(会因缓冲区满/空互相等待)
完整可运行示例
以下代码演示了两个线程通过管道传递 5 个整数(以 4 字节二进制形式):
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos); // 必须先连接
<p>Thread writer = new Thread(() -> {
try (DataOutputStream dos = new DataOutputStream(pos)) {
for (int i = 1; i 10);
System.out.println("写入: " + (i 10));
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
});</p><p>Thread reader = new Thread(() -> {
try (DataInputStream dis = new DataInputStream(pis)) {
for (int i = 0; i </p><p>writer.start();
reader.start();
</p>
运行后将按序输出写入和读取日志,体现字节级同步与阻塞行为。实际使用中建议配合 try-with-resources 确保流及时关闭,防止资源泄漏。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










