简介
PipedOutputStream和PipedInputStream分别是管道输出流和管道输入流。它们的作用是让多线程可以通过管道进行线程间的通讯。在使用管道通信时,必须将PipedOutputStreamPipedInputStream配套使用。
使用管道通信时,大致的流程是:在线程A中向PipedOutputStream中写入数据,这些数据会自动的发送到PipedInputStream中,进而存储在PipedInputStream的缓冲区中;此时,线程B通过读取PipedInputStream中的数据,就可以实现线程A和线程B的通信。
常用方法
- PipedOutputStream
//构造函数,指定与其配对的PipedInputStreampublic,底层调用connect方法
public PipedOutputStream(PipedInputStream snk);
//无参构造
public PipedOutputStream();
//将PipedOutputStream 和 PipedInputSteam绑定
public synchronized void connect(PipedInputStream snk);
//单个字节写入
public void write(int b);
//批量写入
public void write(byte b[], int off, int len);
//刷新缓冲区,目的是让管道输入流放弃对当前资源的占有,
//让其它等待读取管道输出流的线程读取管道输出流的值
public synchronized void flush();
//关闭管道输出流
public void close();
- PipedInputStream
//构造函数,指定与其配对的PipedOutputStream,底层调用connect方法
public PipedInputStream(PipedOutputStream src);
//指定与其配对的PipedOutputStream,以及缓冲区大小(默认缓冲区大小为1024)
public PipedInputStream(PipedOutputStream src, int pipeSize);
//将PipedOutputStream 和 PipedInputSteam绑定
public void connect(PipedOutputStream src);
//接收int类型数据b,它只会在PipedOutputStream的write(int b)中会被调用
protected synchronized void receive(int b);
//接收字节数组b
synchronized void receive(byte b[], int off, int len);
//读取单个字节
public synchronized int read();
//批量读取
public synchronized int read(byte b[], int off, int len);
// 缓冲区可读字节数组的个数
public synchronized int available();
//关闭管道输入流
public void close();
流程
- 实例化管道输入流与管道输出流
- 二者之间建立连接
- 向管道输入流的缓冲区写数据
- 读取缓冲区数据
示例
import java.io.IOException;
import java.io.PipedOutputStream;
/**
* 发送者线程
*/
public class Sender extends Thread {
// 管道输出流对象,它和管道输入流对象绑定
// 从而可以将数据发送给管道输入流,然后用户可以从管道输入流读取数据
private PipedOutputStream out;
//构造方法
public Sender (PipedOutputStream out) {
this.out = out;
}
@Override
public void run() {//继承Thread类,需要重写run()方法
String s = "Hello World";
try {
out.write(s.getBytes());//向管道输入流的缓冲区写入数据
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
import java.io.IOException;
import java.io.PipedInputStream;
/**
* 接收者线程
*/
public class Receiver extends Thread {
// 管道输入流对象,它和管道输出流对象绑定
// 从而可以接收管道输出流的数据,再让用户读取
private PipedInputStream in;
public Receiver(PipedInputStream in) {
this.in = in;
}
@Override
public void run() {//继承Thread类,需要重写run()方法
byte[] bytes = new byte[1024];//管道输入流的缓冲区大小默认1024个字节
try {
int len = in.read(bytes);
System.out.println("缓冲区的内容为: " + new String(bytes, 0, len));
} catch (IOException e) {
e.printStackTrace();
} finally {
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStreamDemo {
public static void main(String[] args) {
/**
* 流程
* 1 建立输入输出流
* 2 绑定输入输出流
* 3 向缓冲区写数据
* 4 读取缓冲区数据
*/
PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream();
Sender sender = new Sender(out);
Receiver receiver = new Receiver(in);
try {
//管道输入流与管道输出流连接,也可以写作in.connect(out);
out.connect(in);
/**
*Thread类的start()方法:开启一个线程
*Java虚拟机调用该线程的run()方法
*/
sender.start();
receiver.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}