管道流是一种特殊的流,他能够支持线程之间的数据交流。一个线程发送数据到输出管道,另一个线程从输入管道中读取数据。通过使用管道实现不同线程之间的通信而无需借助类似临时文件之类的东西。
java提供了4个类支持线程间的通信,分别是
PipedInputStream 和 ; (字节流)
PipedReader 和 PipedWriter; (字符流)
我将用上面两个类列做实例,对于下面两个类的示例其实和上面两个差不多只是将 PipedInputStream 换成PipedReader 将 PipedOutPutStream 换成PipedWriter。
示例如下:
1 新建一个读线程和一个写线程
public class ThreadRead extends Thread{
private PipedInputStream input;
public ThreadRead(PipedInputStream input){
super(); this.input = input;
}
@Override
public void run(){
byte[] array = new byte[30];
int read = 0;
try {
while((read = input.read(array))!=-1){
String string = new String(array, 0, read);
System.out.println(string);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class ThreadWrite extends Thread{
private PipedOutputStream output;
public ThreadWrite(PipedOutputStream output){
super(); this.output = output;
}
@Override
public void run(){
try {
output.write("PipedOutputStream写入数据".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2 新建一个测试类
public class PipeStreamTest {
public static void main(String[] args) throws InterruptedException, IOException {
PipedInputStream inputStream = new PipedInputStream();
PipedOutputStream outputStream = new PipedOutputStream();
// PipedReader inputStream = new PipedReader();
// PipedWriter outputStream = new PipedWriter();
// inputStream.connect(outputStream);
outputStream.connect(inputStream);
//上面这两行代码保证两个stream之间产生通信链接。两行代码用其一即可。
ThreadRead tRead = new ThreadRead(inputStream);
ThreadWrite tWrite = new ThreadWrite(outputStream);
tRead.start(); //先开启读线程,读取输入管道的信息
Thread.sleep(1000);
tWrite.start();//再开启写线程,向输出管道写入信息
}
}
PipedOutputStream写入数据
需要说明的是:我先开启的是读线程,而此时,写线程并没有启动,即在读线程工作的时候,写线程并没有向输出管道写入信息,那么读线程就不可能从输入管道获取信息。但为什么读线程还是打印出信息了呢?
是这样的,由于没有数据被写入,所以读线程阻塞在 read = input.read(array) 这句代码中,知道些线程开始工作并向输出管道写入信息后,读线程才继续运行。