管道

概述

管道流是用来在多个线程之间进行信息传递的Java流。

管道流分为字节流管道流和字符管道流。

字节管道流:PipedOutputStream 和 PipedInputStream。

字符管道流:PipedWriter 和 PipedReader。

字节管道流

这里我们只分析字节管道流,字符管道流原理跟字节管道流一样,只不过底层一个是 byte[] 存储 一个是 char[] 存储的。

java的管道输入与输出实际上使用的是一个循环缓冲数来实现的。

输入流PipedInputStream从这个循环缓冲数组中读数据,输出流PipedOutputStream往这个循环缓冲数组中写入数据。

当这个缓冲数组已满的时候,输出流PipedOutputStream所在的线程将阻塞;当这个缓冲数组为空的时候,输入流PipedInputStream所在的线程将阻塞。

注意事项

  • 管道流仅用于多个线程之间传递信息,若用在同一个线程中可能会造成死锁;

  • 管道流的输入输出是成对的,一个输出流只能对应一个输入流,使用构造函数或者 connect() 函数进行连接;

  • 一对管道流包含一个缓冲区,其默认值为1024个字节,若要改变缓冲区大小,可以使用带有参数的构造函数;

  • 管道的读写操作是互相阻塞的,当缓冲区为空时,读操作阻塞;当缓冲区满时,写操作阻塞;

  • 管道依附于线程,因此若线程结束,则虽然管道流对象还在,仍然会报错“read dead end”;

  • 管道流的读取方法与普通流不同,只有输出流正确close时,输出流才能读到-1值。

实际代码

  • PipeTest
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeTest {

    public static void main(String[] args) throws IOException {

        final PipedOutputStream output = new PipedOutputStream();
        final PipedInputStream input  = new PipedInputStream(output);

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    output.write("Hello world, pipe!".getBytes());
                } catch (IOException e) {
                }
            }
        });


        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int data = input.read();
                    while(data != -1){
                        System.out.print((char) data);
                        data = input.read();
                    }
                } catch (IOException e) {
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

输出日志

Hello world, pipe!

参考资料

http://ifeve.com/java-io-%E7%AE%A1%E9%81%93/

https://blog.csdn.net/yhl_jxy/article/details/79283851

https://www.cnblogs.com/skywang12345/p/io_04.html

https://www.jianshu.com/p/e1416f026c3d

  • 源码分析

https://my.oschina.net/zhangyq1991/blog/1861126