IO--PipedInputSteamAndPipedOutputStream

PipedInputStream和PipedOutputStream在两个线程之间建立通信的管道

比如线程A持有PipedOutputStream os,线程B持有PipedInputStream is,可以用os绑定is也可以用is绑定os。然后os写入数据,is读取数据。

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

/**
 * Created by marsares on 15/7/9.
 */
public class Receiver extends Thread{
    private PipedInputStream in=new PipedInputStream();
    public PipedInputStream getPipedInputStream(){
        return in;
    }
    public Receiver(){}
    public Receiver(Sender s)throws IOException{
        in=new PipedInputStream(s.getPipedOutputStream());
    }
    public void run(){
        try{
            int data;
            while((data=in.read())!=-1){
                System.out.println(data);
            }
            in.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    public static void main(String[]args)throws IOException{
        Receiver r=new Receiver();
        Sender s=new Sender(r);
        s.start();
        r.start();
    }
}
class Sender extends Thread{
    private PipedOutputStream out;
    public PipedOutputStream getPipedOutputStream(){
        return out;
    }
    public Sender(){}
    public Sender(Receiver r)throws IOException{
        out=new PipedOutputStream(r.getPipedInputStream());
    }
    public void run(){
        try{
            for(int i=0;i<100;i++){
                out.write(i);
                //yield();
            }
            out.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
从PipedOutputStream和PipedInputStream源码中可以看出这两者的绑定是对称的,只要有一个在初始化的时候绑定另一个就行了。

PipedInputStream

public PipedInputStream(PipedOutputStream src, int pipeSize)
            throws IOException {
         initPipe(pipeSize);
         connect(src);
    }
PipedOutputStream

public PipedOutputStream(PipedInputStream snk)  throws IOException {
        connect(snk);
    }
PipedOutputStream的write方法调用的PipedInputStream的receive方法,管道流本质上就是在PipedInputStream中的byte[]buffer中读和写。
public void write(int b)  throws IOException {
        if (sink == null) {
            throw new IOException("Pipe not connected");
        }
        sink.receive(b);
    }
但是这就产生一个疑问,如果只是在PipedInputStream中的buffer进行读和写,为什么需要PipedOutputStream呢?

其实管道流还有个重要的特点就是在两个线程之间建立通信通道,如果一个线程关闭了管道能够及时通知另一个线程不再等待。

PipedOutputStream关闭管道

public void close()  throws IOException {
        if (sink != null) {
            sink.receivedLast();
        }
    }
如果buffer中的数据读完并且管道关闭那么PipedInputStream跳出read。如果buffer中数据读完但是管道没有关闭,PipedInputStream将进入阻塞状态等待写进程写入数据。
public synchronized int read()  throws IOException {
        if (!connected) {
            throw new IOException("Pipe not connected");
        } else if (closedByReader) {
            throw new IOException("Pipe closed");
        } else if (writeSide != null && !writeSide.isAlive()
                   && !closedByWriter && (in < 0)) {
            throw new IOException("Write end dead");
        }

        readSide = Thread.currentThread();
        int trials = 2;
        while (in < 0) {
            if (closedByWriter) {
                /* closed by writer, return EOF */
                return -1;
            }
            if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
                throw new IOException("Pipe broken");
            }
            /* might be a writer waiting */
            notifyAll();
            try {
                wait(1000);
            } catch (InterruptedException ex) {
                throw new java.io.InterruptedIOException();
            }
        }
        int ret = buffer[out++] & 0xFF;
        if (out >= buffer.length) {
            out = 0;
        }
        if (in == out) {
            /* now empty */
            in = -1;
        }

        return ret;
    }
如果不使用PipedOutputStream就需要用户自己设定closedByWriter和closedByReader参数,造成了紧耦耦合。

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值