惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Privacy International News Feed
NISL@THU
NISL@THU
Know Your Adversary
Know Your Adversary
G
GRAHAM CLULEY
The Hacker News
The Hacker News
P
Privacy & Cybersecurity Law Blog
S
Schneier on Security
T
Troy Hunt's Blog
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
S
Security Affairs
WordPress大学
WordPress大学
T
Tailwind CSS Blog
博客园 - Franky
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
S
Securelist
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
爱范儿
爱范儿
Help Net Security
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
C
CERT Recently Published Vulnerability Notes
C
Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
Spread Privacy
Spread Privacy
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
博客园 - 司徒正美
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
罗磊的独立博客
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
J
Java Code Geeks
T
Threatpost
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位

博客园 - 时空穿越者

java并发:深入解析 ThreadPoolExecutor.addWorker() 流水线技术解析:处理器重排序的硬件基础 java并发:synchronized 揭秘 java并发:再次认识一下Java中的锁 —— 类级别的锁是否存在? LangGraph:add_conditional_edges详解 Spring异步机制:@Async Spring BeanDefinition Spring Resource Spring之ApplicationContext Spring之BeanFactory:解析getBean()方法 Spring之IoC容器 Spring的整体架构 Spring Data JPA:解析CriteriaQuery Spring Data JPA:解析CriteriaBuilder Spring Data JPA:解析JpaSpecificationExecutor & Specification Spring Data JPA:解析SimpleJpaRepository java并发:线程池之Executors(ScheduledExecutorService篇) java并发:线程池之饱和策略 java并发:线程池之ThreadPoolExecutor
java并发:管道流(Piped Streams)的应用场景
时空穿越者 · 2026-02-08 · via 博客园 - 时空穿越者

管道流(Piped Streams)是Java中用于线程间通信的特殊I/O流,它们通过创建"生产-消费"通道实现数据传输。

核心组件

image

连接方式

方式1:通过构造函数连接(推荐)

// 创建时直接连接
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos); // 建立连接

// 或者反向连接
PipedInputStream pis2 = new PipedInputStream();
PipedOutputStream pos2 = new PipedOutputStream(pis2);

方式2:通过 connect() 方法连接

PipedWriter writer = new PipedWriter();
PipedReader reader = new PipedReader();

// 显式建立连接(必须在读写前调用)
reader.connect(writer); 
// 或 writer.connect(reader);

// 现在可以安全使用
writer.write("Data");
char[] buf = new char[4];
reader.read(buf); // 读取 "Data"

连接机制底层原理

管道流的连接在JVM层创建了一个循环缓冲区

graph LR
    Producer[生产者线程] -->|写入数据| Buffer[循环缓冲区]
    Buffer -->|读取数据| Consumer[消费者线程]

典型应用场景

(1)线程间数据流传递

当两个线程需要顺序处理数据流时,管道流可替代共享变量:

public class PipeConnectionDemo {
    public static void main(String[] args) throws IOException {
        // 创建未连接的流
        PipedWriter writer = new PipedWriter();
        PipedReader reader = new PipedReader();
        
        // 显式建立连接(关键步骤)
        writer.connect(reader); 
        
        Thread producer = new Thread(() -> {
            try {
                writer.write("Hello Pipes!");
                writer.close(); // 关闭流通知结束
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        
        Thread consumer = new Thread(() -> {
            try {
                int charRead;
                while ((charRead = reader.read()) != -1) {
                    System.out.print((char) charRead);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        
        producer.start();
        consumer.start();
    }
}

特点:

避免显式同步,通过流阻塞机制自然协调生产消费节奏

(2)自定义过滤器链

public class FilterChain {
    public static void main(String[] args) throws IOException {
        PipedWriter source = new PipedWriter();
        PipedReader sink = new PipedReader();
        
        // 创建处理链:A → B → C
        Filter filterA = new Filter(source, new PipedWriter());
        Filter filterB = new Filter(filterA.getOutputReader(), new PipedWriter());
        Filter filterC = new Filter(filterB.getOutputReader(), sink);
        
        // 启动过滤器线程
        filterA.start();
        filterB.start();
        filterC.start();
        
        // 写入原始数据
        source.write("Original data");
        source.close();
        
        // 从sink读取最终结果
        System.out.println(sink.read());
    }
}

class Filter extends Thread {
    private final PipedReader in;
    private final PipedWriter out;
    
    public Filter(PipedReader in, PipedWriter out) {
        this.in = in;
        this.out = out;
    }
    
    @Override
    public void run() {
        try {
            int c;
            while ((c = in.read()) != -1) {
                out.write(transform((char) c)); // 自定义转换逻辑
            }
            out.close();
        } catch (IOException e) { e.printStackTrace(); }
    }
    
    private char transform(char c) { ... } // 过滤逻辑
}

多管道连接模式

一对多广播

// 主生产者
PipedOutputStream mainOutput = new PipedOutputStream();

// 创建多个消费者管道
PipedInputStream consumer1 = new PipedInputStream(mainOutput);
PipedInputStream consumer2 = new PipedInputStream(mainOutput);

// 生产者写入的数据会被所有消费者读取
mainOutput.write("Broadcast".getBytes());

备注:实际应用中需考虑线程安全,建议配合BroadcastStream自定义实现

注意事项

必须显式连接:通过构造函数或connect()方法建立管道

缓冲区大小:默认1024字节,可通过PipedInputStream(int)构造函数调整

资源管理:使用try-with-resources确保关闭

try (PipedOutputStream pos = new PipedOutputStream();
     PipedInputStream pis = new PipedInputStream(pos)) {
    // 自动关闭双向流
}

总结

Java管道流的显式连接机制(构造函数或connect())是线程间流式通信的基础。

在多线程场景中,务必在启动线程前完成连接,并通过资源管理确保可靠关闭。