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

 更新时间:2017年10月18日 11:27:00   作者:WAUANG  
这篇文章主要为大家详细介绍了java多线程编程之线程间的通信,探讨使用管道进行通信,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

上一章节讲了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();
  }
 }
}

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

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

相关文章

  • Spring 4.0新功能:@Conditional注解详细介绍

    Spring 4.0新功能:@Conditional注解详细介绍

    Spring Boot的强大之处在于使用了Spring 4框架的新特性:@Conditional注释,此注释使得只有在特定条件满足时才启用一些配置。下面这篇文章主要给大家介绍了关于Spring4.0中新功能:@Conditional注解的相关资料,需要的朋友可以参考下。
    2017-09-09
  • Springboot如何集成jodconverter做文档转换

    Springboot如何集成jodconverter做文档转换

    这篇文章主要介绍了Springboot如何集成jodconverter做文档转换问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • mybatis-plus使用generator实现逆向工程

    mybatis-plus使用generator实现逆向工程

    mybatis-plus-generator在3.5.0以及以后的版本使用新的方式逆向生成代码,本文主要介绍了mybatis-plus使用generator实现逆向工程,具有一定的参考价值,感兴趣的可以了解一下
    2022-05-05
  • Java中JDBC事务与JTA分布式事务总结与区别

    Java中JDBC事务与JTA分布式事务总结与区别

    Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务,本文详细介绍了JDBC事务与JTA分布式事务,有需要的可以了解一下。
    2016-11-11
  • 最新IntelliJ IDEA2017.3 激活方式

    最新IntelliJ IDEA2017.3 激活方式

    本文给大家提供最新IntelliJ IDEA2017.3 激活方式,本文给大家介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2018-01-01
  • SpringBoot @value注解动态刷新问题小结

    SpringBoot @value注解动态刷新问题小结

    @Value注解 所对应的数据源来自项目的 Environment 中,我们可以将数据库或其他文件中的数据,加载到项目的 Environment 中,然后 @Value注解 就可以动态获取到配置信息了,这篇文章主要介绍了SpringBoot @value注解动态刷新,需要的朋友可以参考下
    2023-09-09
  • Java定时清理过期文件的实例代码

    Java定时清理过期文件的实例代码

    这篇文章主要介绍了Java定时清理过期文件的实例代码,非常不错,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2018-12-12
  • Java使用Tinify实现图片无损压缩(4M无损压缩到1M)的方法

    Java使用Tinify实现图片无损压缩(4M无损压缩到1M)的方法

    在当今的数字化时代,图片已成为网站、应用和社交媒体中不可或缺的元素,然而,大尺寸的图片不仅会增加页面或者客户端加载时间,还会占用大量的存储空间,本文将详细介绍如何利用Tinify压缩图片,并将其上传至OSS,重点介绍图片压缩实现方式,需要的朋友可以参考下
    2024-08-08
  • 如何在Spring Boot启动时运行定制的代码

    如何在Spring Boot启动时运行定制的代码

    在本文中您将学习如何挂钩应用程序引导程序生命周期并在Spring Boot启动时执行代码。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • 2023最新版本idea用maven新建web项目(亲测不报错)

    2023最新版本idea用maven新建web项目(亲测不报错)

    这篇文章主要给大家介绍了关于2023最新版本idea用maven新建web项目,Maven是当今Java开发中主流的依赖管理工具,文中介绍的步骤亲测不报错,需要的朋友可以参考下
    2023-07-07

最新评论