线程之间交换信息称为线程通信。线程之间要传送的数据较多,必须使用如共享主存、管道流等通信方式。
管道用来把一个程序输出连接到另一程序输入。java.io中提供了PipedInputStream和PipedOutputStream类作为管道的输入输出部件。
线程使用管道通信一般分为三步:创建输入输出管道流;连接输入输出流管道;向输出流管道写和从输入流管道读。
1.创建管道流
PipedInputStream pis=new PipedInputStream();
PipedOutputStream pos=new PipedOutputStream(pis);
或:
PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream(pos);
2.连接输入输出流管道
在使用管道前,管道输入输出流必须要进行连接。PipedOutputStream类中提供了下面的一些连接方法。
(1) 构造方法中,对于管道输入输出流来说,对应管道输出输入流作为参数以进行连接。
(2) 管道输入输出流还提供了方法connect()以进行相应的连接。
图8-4 管道输入输出流的使用
3.管道流一定是输入输出并用,将数据从输出管道进,从输入管道出,如图8-4所示。
例8-3 两个线程Sender和Receiver,Sender从文件C:/sendFile中顺序读取内容,通过管道输出流发送,而线程Receiver通过管道输入流接收数据。写入文件C:/readFile。注意输出流管道和输入流管道在使用前要连接。
package cha8;
import java.io.*;
public class PipedIO{
public static void main (String args[ ]){
try {
PipedInputStream pis=new PipedInputStream();//构造PipedInputStream对象
PipedOutputStream pos=new PipedOutputStream();//构造PipedOutputStream
对象
pos.connect(pis); //pos与pis连接
new Sender(pos, "sendFile").start(); //构造、启动发送线程
new Receiver(pis, "receiveFile").start(); //构造、启动接收线程
}
catch(IOException e) {
System.out.println("pipe error"+e);
}
}
}
发送线程获得发送文件长度,首先把这个长度发送给接收线程。接收线程也首先接收该长度。然后,发送线程和接收线程利用它控制发送的循环。
package cha8;
import java.io.*;
public class Sender extends Thread {
PipedOutputStream pos;
File file;
Sender(PipedOutputStream pos,String file)
{
this.pos=pos;
this.file=new File(file);
}
public void run() {
try {
FileInputStream fs=new FileInputStream(file);
int i=(int)file.length();//文件长度
pos.write(i);//发送的第1字节是文件长度,用它控制读写的循环
int j=0; //循环变量
while(j<=i)
{int data=fs.read();
pos.write(data);
j++;
}
}catch(IOException e) {
System.out.println("sender error"+e);
}
}
}
接收线程代码如下:
package cha8;
import java.io.*;
public class Receiver extends Thread {
PipedInputStream pis;
File file;
Receiver(PipedInputStream pis, String file) {
this.pis=pis;
this.file=new File(file);
}
public void run() {
try{
FileOutputStream fs=new FileOutputStream(file);
int i=pis.read(); //第1字节是文件长度,用它控制读的循环
int j=0;
while (j<i)
{
int data=pis.read();
fs.write(data);
j++;
}
pis.close();
}catch(IOException e) {
System.out.println("receiver error"+e);
}
}
}
程序运行结束后,receiveFile得到sendFile中的内容。