打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
初学者第67节多线程之管道流(九)
Java 猿程之家
大型互联网项目视频
公告通知

本公众专注于为广大Java初学者和爱好者以及热爱编程的菜鸟提供学习交流平台,共同成长。 如果您发现什么错误、遗漏或不明的地方可以通过文章下留言、群内讨论或私撩小编提出意见反馈,当然小编会给这些奉献的朋友分享Java 大型互联网项目实战视频资料(不定期更新视频资料) ,希望与大家一同成长!!!

引言

在java语言中提供了很多输入与输出流,使我们方便了对数据进行操作,其中管道流是一种特殊的流,用于在不同线程间直接传输数据。一个线程发送到输出管道,另一个线程从输入管道中读取数据。通过使用管道,实现不同线程间的通讯,而无须借助临时文件之类的东西了。

在jdk中提供了4个类来使用线程间可以进行通讯:

    一堆字节流管道流和一堆字符管道流

  1. PipedInputStream

  2. PipedOutputStream

  3. PipedReader

  4. PipedWriter

字节管道流

一般大家都是知道的只要是流基本上都是成对成对出现的,一边写入一遍读取。现在首先讲解一下PipedInputStream和PipedOutputStream这对管道流使用步骤。

建立管道输入端和输出端的连接,必须首先创建一个PipedOutputStream对象,然后创建一个PipedInputStream对象。如下:

      PipedOutputStream out = null;
      PipedInputStream in = null;
对象建立好以后使用connect()方法将二者建立连接
   out.connect(in); 

该方法在PipedOutputStream 、PipedInputStream当中都有,随便调用那个来建立连接都可以,但注意只能建立一次连接,重复建立会抛异常。
不使用connect()方法也是可以建立连接的,方法如下:
   out = new PipedOutputStream(in );
一旦建立了管道,就可以像操作文件一样对管道进行数据读写。

下面线程配合管道流的使用代码编写。

/**
* 写入线程
*/

public class PipedThreadOut implements Runnable {
   /**
    * 管道输出流
    */

   private PipedOutputStream out;
   /**
    * 构造函数
    * @param out
    */

   public PipedThreadOut(PipedOutputStream out) {
       this.out = out;
   }
   /**
    * 写入数据
    */

   private void write() {
       String data = '我是pipedOutputStream流,写入数据了!!!';
       try {
           this.out.write(data.getBytes());
           System.out.println('写入数据为:'+data);

       } catch (IOException e) {
           e.printStackTrace();
       }finally {
           try {
               this.out.close();//关闭输出流
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }
   @Override
   public void run()
{
       //开始写入
       this.write();
   }
}

/**
* 读取线程
*/

class PipedThreadIn implements Runnable {
   /**
    * 管道输出流
    */

   private PipedInputStream in;
   /**
    * 构造函数
    * @param in
    */

   public PipedThreadIn(PipedInputStream in) {
       this.in = in;
   }
   /**
    * 读取数据
    */

   private void read() {
       //定义一个缓冲区
       byte[] b = new byte[1024];
       //记录读取字节数
       int len;
       String data = '';
       try {
           //开始读取
           while ((len = this.in.read(b)) > 0) {
               data += new String(b,0,len);
           }
           System.out.println('读取数据为:' + data);
       } catch (IOException e) {
           e.printStackTrace();
       }finally {
           try {
               this.in.close();//关闭读取流
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       System.out.println('=====================================');
   }
   @Override
   public void run()
{
       //开始读取
       this.read();
   }
}


调用代码

public class PipedThreadTest {
   public static void main(String[] args) throws IOException, InterruptedException {
       //创建写入流
       PipedOutputStream out = new PipedOutputStream();
       //创建读取流
       PipedInputStream in = new PipedInputStream();
       //为写入和读取建立连接
       out.connect(in);
       //创建写入流线程
       Thread outThread = new Thread(new PipedThreadOut(out));
       //创建读取流线程
       Thread inThread = new Thread(new PipedThreadIn(in));
       //启动线程
       outThread.start();
       Thread.sleep(1000);
       inThread.start();
   }
}

结果:
写入数据为:我是pipedOutputStream流,写入数据了!!!
读取数据为:我是pipedOutputStream流,写入数据了!!!
=====================================

解释一下代码编写的过程

    1.首先创建一个输出管道的runnable的实现类作为写入数据线程类使用,写入数据需要传入一个输出管道流对象。

    2. 在创建一个输入管道的runnable的实现类作为读取数据的线程类使用,读取数据需要传入一个输入管道流对象。

    3. 在测试类创建一个输出流对象和一个输入流对象。

    4. 在创建2个线程将输出和输入对象传到各自对应的runnable的实现类中

    5. 最后启动2个线程。

注意:一定要将输入和输出流简历连接connect

字符管道流

字符管道流和字节管道流几乎是一模一样的使用,只需要将输入字节流修改成字符流,以及将输出字节流修改为输出字符流,并且需要将读取缓冲区的byte数组修改为char数组即可。直接看代码吧!!!

/**
* 写入线程
*/

public class PipedThreadOut implements Runnable {
   /**
    * 管道输出流
    */

   private PipedWriter out;
   /**
    * 构造函数
    * @param out
    */

   public PipedThreadOut(PipedWriter out) {
       this.out = out;
   }
   /**
    * 写入数据
    */

   private void write() {
       String data = '我是pipedWrite流,写入数据了!!!';
       try {
           this.out.write(data);
           System.out.println('写入数据为:'+data);

       } catch (IOException e) {
           e.printStackTrace();
       }finally {
           try {
               this.out.close();//关闭输出流
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }
   @Override
   public void run()
{
       //开始写入
       this.write();
   }
}

/**
* 读取线程
*/

class PipedThreadIn implements Runnable {
   /**
    * 管道输出流
    */

   private PipedReader in;
   /**
    * 构造函数
    * @param in
    */

   public PipedThreadIn(PipedReader in) {
       this.in = in;
   }
   /**
    * 读取数据
    */

   private void read() {
       //定义一个缓冲区
       char[] b = new char[1024];
       //记录读取字节数
       int len;
       String data = '';
       try {
           //开始读取
           while ((len = this.in.read(b)) > 0) {
               data += new String(b,0,len);
           }
           System.out.println('读取数据为:' + data);
       } catch (IOException e) {
           e.printStackTrace();
       }finally {
           try {
               this.in.close();//关闭读取流
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       System.out.println('=====================================');
   }
   @Override
   public void run()
{
       //开始读取
       this.read();
   }
}


测试运行代码

public class PipedThreadTest {
   public static void main(String[] args) throws IOException, InterruptedException {
       //创建写入流
       PipedWriter out = new PipedWriter();
       //创建读取流
       PipedReader in = new PipedReader();
       //为写入和读取建立连接
       out.connect(in);
       //创建写入流线程
       Thread outThread = new Thread(new PipedThreadOut(out));
       //创建读取流线程
       Thread inThread = new Thread(new PipedThreadIn(in));
       //启动线程
       outThread.start();
       Thread.sleep(1000);
       inThread.start();
   }
}

运行结果:

写入数据为:我是pipedWrite流,写入数据了!!!
读取数据为:我是pipedWrite流,写入数据了!!!
=====================================

好了管道流比较简单,和前面学习的流差不多,只是配合线程使用了一下。

✎备注

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java 线程间通讯(管道流方式)
举例讲解Java中Piped管道输入输出流的线程通信控制
将输出流(OutputStream)转化为输入流(InputStream)的方法(二)
FileInputStream/FileOutputStream的应用
在Java程序中截获控制台输出(ZT)
Java中常用的输入输出流
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服