java多线程编程之管道通信详解
上一章节讲了wait/notify通信,这一节我们来探讨使用管道进行通信。
java中提供了IO流使我们很方便的对数据进行操作,pipeStream是一种特殊的流,用于不同线程间直接传送数据。一个线程将数据发送到输出管道,另一个线程从输入管道读取数据。通过管道实现通信不需要借助临时文件这类东西。
java中提供了四个类使得线程间可以通信:
①字节流:PipeInputStream,PipedOutputStream
②字符流:PipedReader,PipedWriter
下面我们看看字节流的实现方法:
packagepipeInputOutput;
//输出流
importjava.io.IOException;
importjava.io.PipedOutputStream;
publicclassWriteDate{
publicvoidwriteMethod(PipedOutputStreamout){
try{
System.out.println("write:");
for(inti=0;i<300;i++){
StringoutDate=""+(i+1);
out.write(outDate.getBytes());
System.out.print(outDate);
}
System.out.println();
out.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
packagepipeInputOutput;
//输入流
importjava.io.IOException;
importjava.io.PipedInputStream;
publicclassReadDate{
publicvoidReadDate(PipedInputStreaminput){
try{
System.out.println("read:");
byte[]byteArray=newbyte[20];
intreadLength=input.read(byteArray);
while(readLength!=-1){
StringnewDate=newString(byteArray,0,readLength);
System.out.print(newDate);
readLength=input.read(byteArray);
}
System.out.println();
input.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
packagepipeInputOutput;
importjava.io.PipedOutputStream;
//输出线程
publicclassThreadWriteextendsThread{
privateWriteDatewrite;
privatePipedOutputStreamout;
publicThreadWrite(WriteDatewrite,PipedOutputStreamout){
super();
this.write=write;
this.out=out;
}
publicvoidrun(){
write.writeMethod(out);
}
}
packagepipeInputOutput;
importjava.io.PipedInputStream;
//输入线程
publicclassThreadReadextendsThread{
privateReadDateread;
privatePipedInputStreamin;
publicThreadRead(ReadDateread,PipedInputStreamin){
super();
this.read=read;
this.in=in;
}
publicvoidrun(){
read.ReadDate(in);
}
}
packagepipeInputOutput;
importjava.io.IOException;
importjava.io.PipedInputStream;
importjava.io.PipedOutputStream;
//测试方法
publicclassRun{
publicstaticvoidmain(String[]args){
try{
WriteDatewrite=newWriteDate();
ReadDateread=newReadDate();
PipedInputStreaminputStream=newPipedInputStream();
PipedOutputStreamoutputStream=newPipedOutputStream();
//输出流与输入流进行连接。
outputStream.connect(inputStream);
//inputStream.connect(outputStream);
ThreadReadreadThread=newThreadRead(read,inputStream);
readThread.start();//先启动输出线程
Thread.sleep(2000);
ThreadWritewriteThread=newThreadWrite(write,outputStream);
writeThread.start();//后启动输入线程
}catch(IOExceptione){
e.printStackTrace();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
控制台输出:
read:
write:
123456789101112131415161718192021...
123456789101112131415161718192021...
上面测试中,先启动输入线程,然后因为没有线程被写入所以线程被阻塞,知道有数据写入。
我们接着继续看看字符流的实现方法:
packagepipeInputOutput1;
importjava.io.IOException;
importjava.io.PipedWriter;
//字符输出流
publicclassWriteDate{
publicvoidwriteMethod(PipedWriterout){
try{
System.out.println("write:");
for(inti=0;i<300;i++){
StringoutDate=""+(i+1);
out.write(outDate);
System.out.print(outDate);
}
System.out.println();
out.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
packagepipeInputOutput1;
importjava.io.IOException;
importjava.io.PipedReader;
//字符输入流
publicclassReadDate{
publicvoidreadMethod(PipedReaderin){
try{
System.out.println("read:");
char[]byteArray=newchar[20];
intreadLength=in.read(byteArray);
while(readLength!=-1){
StringnewDate=newString(byteArray,0,readLength);
System.out.print(newDate);
readLength=in.read(byteArray);
}
System.out.println();
in.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
packagepipeInputOutput1;
importjava.io.PipedWriter;
//输出流线程
publicclassWriteThreadextendsThread{
privateWriteDatewrite;
privatePipedWriterout;
publicWriteThread(WriteDatewrite,PipedWriterout){
super();
this.write=write;
this.out=out;
}
publicvoidrun(){
write.writeMethod(out);
}
}
packagepipeInputOutput1;
importjava.io.PipedReader;
//输入流线程
publicclassReadThreadextendsThread{
privateReadDateread;
privatePipedReaderin;
publicReadThread(ReadDateread,PipedReaderin){
super();
this.read=read;
this.in=in;
}
publicvoidrun(){
read.readMethod(in);
}
}
packagepipeInputOutput1;
importjava.io.IOException;
importjava.io.PipedReader;
importjava.io.PipedWriter;
//测试方法
publicclassrun{
publicstaticvoidmain(String[]args){
try{
WriteDatewrite=newWriteDate();
ReadDateread=newReadDate();
PipedWriterout=newPipedWriter();
PipedReaderin=newPipedReader();
//连接输出流与输入流
out.connect(in);
//in.connect(out);
ReadThreadthreadread=newReadThread(read,in);
threadread.start();
Thread.sleep(2000);
WriteThreadthreadwrite=newWriteThread(write,out);
threadwrite.start();
}catch(IOExceptione){
e.printStackTrace();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
字符流额字节流大同小异,上面的例子中字符流不需要创建字节数组而已。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。