欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java多线程编程之管道通信详解

程序员文章站 2024-02-23 08:29:28
上一章节讲了wait/notify通信,这一节我们来探讨使用管道进行通信。 java中提供了io流使我们很方便的对数据进行操作,pipestream是一种特殊的流,...

上一章节讲了wait/notify通信,这一节我们来探讨使用管道进行通信。

java中提供了io流使我们很方便的对数据进行操作,pipestream是一种特殊的流,用于不同线程间直接传送数据。一个线程将数据发送到输出管道,另一个线程从输入管道读取数据。通过管道实现通信不需要借助临时文件这类东西。

java中提供了四个类使得线程间可以通信:

①字节流:pipeinputstream,pipedoutputstream
②字符流:pipedreader,pipedwriter

下面我们看看字节流的实现方法:

package pipeinputoutput;
//输出流
import java.io.ioexception;
import java.io.pipedoutputstream;
public class writedate {
 public void writemethod(pipedoutputstream out) {
  try {
   system.out.println("write:");
   for(int i=0;i<300;i++) {
    string outdate=""+(i+1);
    out.write(outdate.getbytes());
    system.out.print(outdate);
   }
   system.out.println();
   out.close();
  }catch(ioexception e) {
   e.printstacktrace();
  }
 }
}

package pipeinputoutput;
//输入流
import java.io.ioexception;
import java.io.pipedinputstream;

public class readdate {
 public void readdate(pipedinputstream input) {
  try {
   system.out.println("read:");
   byte[] bytearray=new byte[20];
   int readlength=input.read(bytearray);
   while(readlength!=-1) {
    string newdate=new string(bytearray,0,readlength);
    system.out.print(newdate);
    readlength=input.read(bytearray);
   }
   system.out.println();
   input.close();
  }catch(ioexception e){
   e.printstacktrace();
  } 
 }
}

package pipeinputoutput;
import java.io.pipedoutputstream;
//输出线程
public class threadwrite extends thread {
 private writedate write;
 private pipedoutputstream out;

 public threadwrite(writedate write,pipedoutputstream out) {
  super();
  this.write=write;
  this.out=out;
 }
 public void run() {
  write.writemethod(out);
 }

}
package pipeinputoutput;
import java.io.pipedinputstream;
//输入线程
public class threadread extends thread{
 private readdate read;
 private pipedinputstream in;
 public threadread(readdate read,pipedinputstream in) {
  super();
  this.read=read;
  this.in=in;
 }
 public void run() {
  read.readdate(in);
 }

}


package pipeinputoutput;
import java.io.ioexception;
import java.io.pipedinputstream;
import java.io.pipedoutputstream;
//测试方法
public class run {
 public static void main(string[] args) {
  try {
   writedate write=new writedate();
   readdate read=new readdate();
   pipedinputstream inputstream=new pipedinputstream();
   pipedoutputstream outputstream=new pipedoutputstream();
   //输出流与输入流进行连接。
   outputstream.connect(inputstream);
   //inputstream.connect(outputstream);
   threadread readthread=new threadread(read,inputstream);
   readthread.start();//先启动输出线程
   thread.sleep(2000);
   threadwrite writethread=new threadwrite(write,outputstream);
   writethread.start();//后启动输入线程
  } catch (ioexception e) {
   e.printstacktrace();
  } catch (interruptedexception e) {
   e.printstacktrace();
  }
 }

}

控制台输出:

read:
write:
123456789101112131415161718192021...
123456789101112131415161718192021...

上面测试中,先启动输入线程,然后因为没有线程被写入所以线程被阻塞,知道有数据写入。

我们接着继续看看字符流的实现方法:

package pipeinputoutput1;
import java.io.ioexception;
import java.io.pipedwriter;
//字符输出流
public class writedate {
 public void writemethod(pipedwriter out) {
  try {
   system.out.println("write:");
   for(int i=0;i<300;i++) {
    string outdate=""+(i+1);
    out.write(outdate);
    system.out.print(outdate);
   }
   system.out.println();
   out.close();
  }catch(ioexception e) {
   e.printstacktrace();

  }
 }

}

package pipeinputoutput1;
import java.io.ioexception;
import java.io.pipedreader;
//字符输入流
public class readdate {
 public void readmethod(pipedreader in) {

  try {
   system.out.println("read:");
   char[] bytearray=new char[20];
   int readlength=in.read(bytearray);
   while(readlength!=-1) {
    string newdate=new string(bytearray,0,readlength);
    system.out.print(newdate);
    readlength=in.read(bytearray);
   }
   system.out.println();
   in.close();
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }

}

package pipeinputoutput1;
import java.io.pipedwriter;
//输出流线程
public class writethread extends thread {
 private writedate write;
 private pipedwriter out;
 public writethread(writedate write,pipedwriter out) {
  super();
  this.write=write;
  this.out=out;
 }

 public void run() {
  write.writemethod(out);
 }

}

package pipeinputoutput1;
import java.io.pipedreader;
//输入流线程
public class readthread extends thread{
 private readdate read;
 private pipedreader in;
 public readthread(readdate read,pipedreader in) {
  super();
  this.read=read;
  this.in=in;
 }
 public void run() {
  read.readmethod(in);
 }

}

package pipeinputoutput1;
import java.io.ioexception;
import java.io.pipedreader;
import java.io.pipedwriter;
//测试方法
public class run {
 public static void main(string[] args) {
  try {
   writedate write=new writedate();
   readdate read=new readdate();

   pipedwriter out=new pipedwriter();
   pipedreader in=new pipedreader();
   //连接输出流与输入流
   out.connect(in);
   //in.connect(out);
   readthread threadread=new readthread(read,in);
   threadread.start();

   thread.sleep(2000);
   writethread threadwrite=new writethread(write,out);
   threadwrite.start();
  } catch (ioexception e) {
   e.printstacktrace();
  } catch (interruptedexception e) {
   e.printstacktrace();
  }
 }
}

字符流额字节流大同小异,上面的例子中字符流不需要创建字节数组而已。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。