PipedInputStream 继承自 InputStream 类。
PipedOutputSteam 继承自 OutputStream 类。
在使用管道通信时,必须将 PipedOutputStream 和 PipedInputStream 配套使用。它们的作用是让多线程可以通过管道进行线程间的通讯。
使用管道通信时,大致的流程是:在线程A中向 PipedOutputStream 中写入数据,这些数据会自动的发送到与PipedOutputStream 对应的 PipedInputStream 中,进而存储在 PipedInputStream 的缓冲中;此时,线程B通过读取PipedInputStream 中的数据,就可以实现线程 A 和线程 B的通信。
PipedInputStream 定义了缓冲数组和其他的一些属性,而 PipedOutputStream 中只是引用了连接的 输入流对象,定义了一些方法来操作输入流对象的属性等。
两个类的代码都比较易懂,下边两个类一起进行分析:
属性
PipedInputStream:
boolean closedByWriter = false;
volatile boolean closedByReader = false;
// 管道输入流和管道输出流是否已经连接
// (这个变量的值是在connect方法中改变的,在输出流的类中实现的)
boolean connected = false;
Thread readSide;
Thread writeSide;
private static final int DEFAULT_PIPE_SIZE = 1024;
// 循环缓冲区字节数组的大小为默认大小1024
protected static final int PIPE_SIZE = DEFAULT_PIPE_SIZE;
// 循环缓冲区,放置传入的数据
protected byte buffer[];
// 从管道输出流接受下一个字节时,存储到字节数组的此下标的位置
protected int in = -1;
// 管道输入流从该下标位置读取下一个字节
protected int out = 0;
构造函数
构造函数中,调用了 initPipe 方法来根据给定大小来初始化缓冲字节数组,另外也可以指定连接的 管道输出流 PipedOutputStream 对象,使用 connect 方法来建立二者的连接。
// 无参构造函数,调用初始化缓冲数组方法initPipe,使用默认大小
public PipedInputStream() {
initPipe(DEFAULT_PIPE_SIZE);
}
// 根据给定的管道大小来建立缓冲字节数组
private void initPipe(int pipeSize) {
if (pipeSize <= 0) {
throw new IllegalArgumentException("Pipe Size <= 0");
}
buffer = new byte[pipeSize];
}
// 给定管道缓冲数组大小来建立
public PipedInputStream(int pipeSize) {
initPipe(pipeSize);
}
// 初始化缓冲数组,并且连接到指定的管道输出流
public PipedInputStream(PipedOutputStream src, int pipeSize)
throws IOException {
initPipe(pipeSize);
connect(src);
}
// 将管道输入流和管道输出流连接起来,connect方法二者谁连接谁效果一样
public void connect(PipedOutputStream src) throws IOException {
src.connect(this);
}
// 使用给定的管道输出流和默认的缓冲数组大小来建立管道输入流
public PipedInputStream(PipedOutputStream src) throws IOException {
this(src, DEFAULT_PIPE_SIZE);
}
这里的 connect 方法,在 PipedOutputStream 类中: