博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发编程线程通信之管道流
阅读量:6114 次
发布时间:2019-06-21

本文共 2284 字,大约阅读时间需要 7 分钟。

1240

前言

在并发编程中,需要处理两个问题:线程之间如何通信及线程之间如何同步。通知是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递

在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信。而子啊消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来显式进行通信。

Java 的并发才作用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。

而Java中还有另一种用的比较少的线程间的通信方式:管道流。

如何使用?

管道输入/输入流和普通的文件输入/输出流或者网络输入/输出流不同之处在于,它主要用于线程之间的数据传输,而传输的媒介为内存。

管道输入/输入流主要包括了如下4种具体实现:PipedOutputStream,PipedInputStream,PipedReader 和 PipedWriter,前两种面向字节,而后两种面向字符。

我们先来一个例子看看:

public class PipedStreamDemo {  public static void main(String[] args) throws IOException {    PipedWriter writer = new PipedWriter();    PipedReader reader = new PipedReader();    PipedInputStream inputStream = new PipedInputStream();    PipedOutputStream outputStream = new PipedOutputStream();    // 将输出流和输入流连接    writer.connect(reader);    Thread printThread = new Thread(new Print(reader));    printThread.start();    int receive;    try {      while ((receive = System.in.read()) != -1) {        // 从main线程写到 print 线程        writer.write(receive);      }    } finally {      writer.close();    }  }  static class Print implements Runnable {    private PipedReader in;    public Print(PipedReader in) {      this.in = in;    }    @Override    public void run() {      int receive;      try {        while ((receive = in.read()) != -1) {          // 读取 main 线程发送过来的数据并打印          System.out.print((char) receive);        }      } catch (Exception e) {        e.printStackTrace();      }    }  }}

上面的代码种,创建了 printThread,它用来接受 main 线程的输入,任何 main 线程的输入均通过 PipedWriter 写入,而 printThread 在另一端通过 PipedReader 将内容读出并打印。

对于 Piped 类型的流,必须先要进行绑定,也就是调用 connect 方法,如果没有将输入 / 输出流绑定起来,对于该流的访问将会抛出异常。

而作为这两个类连接的重要方法 connect 方法式如何实现的呢?

public synchronized void connect(PipedReader snk) throws IOException {        if (snk == null) {            throw new NullPointerException();        } else if (sink != null || snk.connected) {            throw new IOException("Already connected");        } else if (snk.closedByReader || closed) {            throw new IOException("Pipe closed");        }        sink = snk;        snk.in = -1;        snk.out = 0;        snk.connected = true;    }

首先参数判断,然后将输入流设置为输出流的 sink 属性。这样就将两个流关联了起来。实现了两个线程的通信。

总结

总的来说,该类的应用场景并不是很多,只是我们应该知道另一种线程通信的方式。嗯,就酱。

good luck !!!!

转载于:https://www.cnblogs.com/stateis0/p/9062024.html

你可能感兴趣的文章
PC-BSD 9.2 发布,基于 FreeBSD 9.2
查看>>
网卡驱动程序之框架(一)
查看>>
css斜线
查看>>
Windows phone 8 学习笔记(3) 通信
查看>>
重新想象 Windows 8 Store Apps (18) - 绘图: Shape, Path, Stroke, Brush
查看>>
Revit API找到风管穿过的墙(当前文档和链接文档)
查看>>
Scroll Depth – 衡量页面滚动的 Google 分析插件
查看>>
Windows 8.1 应用再出发 - 视图状态的更新
查看>>
自己制作交叉编译工具链
查看>>
Qt Style Sheet实践(四):行文本编辑框QLineEdit及自动补全
查看>>
[物理学与PDEs]第3章习题1 只有一个非零分量的磁场
查看>>
深入浅出NodeJS——数据通信,NET模块运行机制
查看>>
onInterceptTouchEvent和onTouchEvent调用时序
查看>>
android防止内存溢出浅析
查看>>
4.3.3版本之引擎bug
查看>>
SQL Server表分区详解
查看>>
使用FMDB最新v2.3版本教程
查看>>
SSIS从理论到实战,再到应用(3)----SSIS包的变量,约束,常用容器
查看>>
STM32启动过程--启动文件--分析
查看>>
垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
查看>>