1. 首页
  2. 网络编程教程

008-八、网络编程之多线程之管道流

引言

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


PipedInputStream PipedOutputStream PipedReader PipedWriter

字节管道流

一般大家都是知道的只要是流基本上都是成对成对出现的,一边写入一遍读取。现在首先讲解一下 PipedInputStreamPipedOutputStream 这对管道流使用步骤。
建立管道输入端和输出端的连接,必须首先创建一个 PipedOutputStream 对象,然后创建一个 PipedInputStream 对象。如下:


PipedOutputStream out = null; PipedInputStream in = null;

对象建立好以后使用 connect() 方法将二者建立连接


out.connect(in);

该方法在 PipedOutputStreamPipedInputStream 当中都有,随便调用那个来建立连接都可以,但注意只能建立一次连接,重复建立会抛异常。
不使用 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流,写入数据了!!! =====================================

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

写完了如果写得有什么问题,希望读者能够给小编留言,也可以点击[此处扫下面二维码关注微信公众号](https://www.ycbbs.vip/?p=28 "此处扫下面二维码关注微信公众号")

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「方志朋」,公众号后台回复「666」 免费领取我精心整理的进阶资源教程
  4. JS中文网,Javascriptc中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,是给开发者用的 Hacker News,技术文章由为你筛选出最优质的干货,其中包括:Android、iOS、前端、后端等方面的内容。目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。

    本文著作权归作者所有,如若转载,请注明出处

    转载请注明:文章转载自「 Java极客技术学习 」https://www.javajike.com

    标题:008-八、网络编程之多线程之管道流

    链接:https://www.javajike.com/article/1231.html

« 009-九、网络编程之多线程之单例模式
007-七、网络编程之生产者消费者(二)»

相关推荐

QR code