本文主要是介绍PipedInputStream,PipedOutputStream源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
PipedInputStream类与PipedOutputStream类用于在应用程序中创建管道通信.一个PipedInputStream实例对象必须和一个PipedOutputStream实例对象进行连接而产生一个通信管道.PipedOutputStream可以向管道中写入数据,PipedIntputStream可以读取PipedOutputStream向管道中写入的数据.这两个类主要用来完成线程之间的通信.一个线程的PipedInputStream对象能够从另外一个线程的PipedOutputStream对象中读取数据.
首先简单的介绍一下这两个类的实现原理,PipedInputStream和PipedOutputStream的实现原理类似于"生产者-消费者"原理,PipedOutputStream是生产者,PipedInputStream是消费者,在PipedInputStream中有一个buffer字节数组,默认大小为1024,作为缓冲区,存放"生产者"生产出来的东东.还有两个变量,in,out,in是用来记录"生产者"生产了多少,out是用来记录"消费者"消费了多少,in为-1表示消费完了,in==out表示生产满了.当消费者没东西可消费的时候,也就是当in为-1的时候,消费者会一直等待,直到有东西可消费.
protected synchronized void receive(int b) throws IOException {// 这里好像有些问题,因为这个方法是在PipedOutputStream类中调用的,而这个方法是protected的,下面另一个receive方法就不是protected,可能是我的源码有些问题,也请大家帮我看看
checkStateForReceive();// 检测通道是否连接,准备好接收产品
writeSide = Thread.currentThread();// 当前线程是生产者
if (in == out)
awaitSpace();// 发现通道满了,没地方放东西啦,等吧~~
if (in < 0) {// in<0,表示通道是空的,将生产和消费的位置都置成第一个位置
in = 0;
out = 0;
}
buffer[in++] = (byte) (b & 0xFF);
if (in >= buffer.length) {// 如果生产位置到达了通道的末尾,为了循环利用通道,将in置成0
in = 0;
}
}
synchronized void receive(byte b[], int off, int len) throws IOException {// 看,这个方法不是protected的!
checkStateForReceive();
writeSide = Thread.currentThread();
int bytesToTransfer = len;// 需要接收多少产品的数量
while (bytesToTransfer > 0) {
if (in == out)
awaitSpace();
int nextTransferAmount = 0;// 本次实际可以接收的数量
if (out < in) {
nextTransferAmount = buffer.length - in;// 如果消费的当前位置<生产的当前位置,则还可以再生产buffer.length-in这么多
} else if (in < out) {
if (in == -1) {
in = out = 0;// 如果已经消费完,则将in,out置成0,从头开始接收
nextTransferAmount = buffer.length - in;
} else {
nextTransferAmount = out - in;// 如果消费的当前位置>生产的当前位置,而且还没消费完,那么至少还可以再生产out-in这么多,注意,这种情况是因为通道被重复利用而产生的!
}
}
if (nextTransferAmount > bytesToTransfer)// 如果本次实际可以接收的数量要大于当前传过来的数量,
nextTransferAmount = bytesToTransfer;// 那么本次实际只能接收当前传过来的这么多了
assert (nextTransferAmount > 0);
System.arraycopy(b, off, buffer, in, nextTransferAmount);// 把本次实际接收的数量放进通道
bytesToTransfer -= nextTransferAmount;// 算出还剩多少需要放进通道
off += nextTransferAmount;
in += nextTransferAmount;
if (in >= buffer.length) {// 到末尾了,该从头开始了
in = 0;
}
}
}
消费产品的行为:























































































这篇关于PipedInputStream,PipedOutputStream源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!