关闭

IO--PipedInputSteamAndPipedOutputStream

标签: IOPipedOutputStreamPipedInputStream线程管道
81人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6055次
    • 积分:517
    • 等级:
    • 排名:千里之外
    • 原创:48篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类