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(); } } }
字符流额字节流大同小异,上面的例子中字符流不需要创建字节数组而已。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。