导读:本期聚焦于小伙伴创作的《如何在 Java 中使用 PipedReader 和 PipedWriter 实现两个本地线程间的字符通讯》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在 Java 中使用 PipedReader 和 PipedWriter 实现两个本地线程间的字符通讯》有用,将其分享出去将是对创作者最好的鼓励。

在Java的IO流体系中,PipedReader和PipedWriter是用于线程间字符通讯的一对管道流,它们可以在两个运行中的本地线程之间传递字符数据,不需要借助额外的共享变量或者外部存储。

如何在 Java 中使用 PipedReader 和 PipedWriter 实现两个本地线程间的字符通讯

PipedReader和PipedWriter的核心特性

PipedReader是字符管道输入流,用于读取管道中的字符数据;PipedWriter是字符管道输出流,用于向管道中写入字符数据。两者需要配对使用,通常一个线程作为写入方,另一个线程作为读取方,通过管道建立连接后就可以实现数据的单向传递。

需要注意的是,这两个流本身没有线程安全的保证,因此一般建议一个PipedWriter只对应一个写入线程,一个PipedReader只对应一个读取线程,避免多线程操作同一个流导致数据混乱。

建立管道连接的两种方式

使用PipedReader和PipedWriter实现通讯,首先需要建立两者的连接,有两种常用的连接方式:

方式一:通过构造方法连接

可以在创建PipedReader的时候,直接传入PipedWriter对象完成连接,示例代码如下:

import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class PipeConnectDemo1 {
    public static void main(String[] args) throws IOException {
        // 创建管道输出流
        PipedWriter writer = new PipedWriter();
        // 创建管道输入流,并和输出流绑定
        PipedReader reader = new PipedReader(writer);
        System.out.println("管道连接成功");
    }
}

方式二:通过connect方法连接

也可以先分别创建两个流对象,之后调用PipedReader或者PipedWriter的connect方法建立连接,示例代码如下:

import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class PipeConnectDemo2 {
    public static void main(String[] args) throws IOException {
        PipedWriter writer = new PipedWriter();
        PipedReader reader = new PipedReader();
        // 调用connect方法建立连接
        writer.connect(reader);
        // 也可以写成 reader.connect(writer),效果一致
        System.out.println("管道连接成功");
    }
}

完整的线程间字符通讯示例

下面通过一个完整的示例,展示两个本地线程如何通过PipedReader和PipedWriter实现字符通讯:一个线程负责写入字符串数据,另一个线程负责读取并打印数据。

import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class ThreadCharCommunicate {
    public static void main(String[] args) {
        try {
            // 创建管道输出流和输入流
            PipedWriter pipedWriter = new PipedWriter();
            PipedReader pipedReader = new PipedReader();
            // 建立连接
            pipedWriter.connect(pipedReader);

            // 创建写入线程,负责向管道写入字符数据
            Thread writeThread = new Thread(() -> {
                try {
                    String message = "这是来自写入线程的字符消息";
                    System.out.println("写入线程开始写入数据:" + message);
                    // 写入字符数据
                    pipedWriter.write(message);
                    // 写入完成后关闭流
                    pipedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }, "write-thread");

            // 创建读取线程,负责从管道读取字符数据
            Thread readThread = new Thread(() -> {
                try {
                    // 用于临时存储读取的字符
                    StringBuilder result = new StringBuilder();
                    int readChar;
                    // 循环读取管道中的字符,read方法返回-1表示流结束
                    while ((readChar = pipedReader.read()) != -1) {
                        result.append((char) readChar);
                    }
                    System.out.println("读取线程接收到数据:" + result.toString());
                    // 读取完成后关闭流
                    pipedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }, "read-thread");

            // 启动两个线程
            writeThread.start();
            readThread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行上述代码,输出结果如下:

写入线程开始写入数据:这是来自写入线程的字符消息
读取线程接收到数据:这是来自写入线程的字符消息

使用注意事项

  • 管道流的连接必须在读写操作之前完成,否则会抛出IOException异常。
  • 写入线程写入数据后,如果没有关闭输出流,读取线程的read方法会一直阻塞等待新数据,因此写入完成后需要及时关闭流,或者在写入结束标记让读取线程知道数据已经传输完毕。
  • 如果读取线程先启动,在没有数据可读的时候,read方法会进入阻塞状态,直到有数据写入或者流被关闭。
  • 不要对同一个管道流进行双向读写,PipedReader和PipedWriter是单向传输设计,双向通讯需要创建两对管道流分别处理两个方向的数据。
  • 如果需要在多个线程之间传递对象数据,不建议使用字符管道流,更适合使用ObjectOutputStream和ObjectInputStream配合PipedOutputStream、PipedInputStream实现。

常见问题解答

为什么读取线程会阻塞?

当管道中没有数据可读,且对应的PipedWriter没有关闭时,PipedReader的read方法会一直阻塞,直到有新的数据写入或者流被关闭。这是正常的阻塞特性,不需要额外处理,只需要在写入完成后正确关闭流即可。

可以多个线程同时写入同一个PipedWriter吗?

不建议这样做,PipedWriter本身不是线程安全的,多个线程同时写入可能会导致数据错乱,如果需要多个线程写入,需要自己添加同步锁保证同一时间只有一个线程执行写入操作。

PipedReaderPipedWriterJava线程通讯修改时间:2026-07-13 19:03:27

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。