Java使用管道实现进程间通讯
来源:互联网 发布:杭州运维前哨网络骗局 编辑:程序博客网 时间:2024/05/16 19:28
常见的进程间通信方式:
- 管道通信
- 共享内存
- Socket
Java进程通讯
Java没有共享内存机制,同时Java的管道也只能用于Java线程间的通讯。
下面是一个关于Java的管道简单的介绍:
Java提供管道功能,实现管道通信的类有两组:PipedInputStream和PipedOutputStream或者是PipedReader和PipedWriter。管道通信主要用于不同线程间的通信。一个PipedInputStream实例对象必须和一个PipedOutputStream实例对象进行连接而产生一个通信管道。PipedOutputStream向管道中写入数据,PipedIntputStream读取PipedOutputStream向管道中写入的数据。一个线程的PipedInputStream对象能够从另外一个线程的PipedOutputStream对象中读取数据。
看来Java只能通过Socket实现进程间通讯了。Socket本身确实具有很好的通用性,而且可以跨主机通讯。但是Scoket本身也有一些弱点,如效率相对其他方式较低,开发成本较高等。最重要的是,这篇文章我们要介绍的是Java如何使用PIPE实现进程间通讯。所以只好委屈一下Socket了。
Java通过管道实现进程通讯
管道的本质
首先,我们需要说明一个基本概念:什么是管道?
管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。有名管道叫named pipe或者FIFO(先进先出),可以用函数mkfifo()创建。
Linux管道的实现机制
从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为:·
1)限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。
2)读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题
注意:
从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛 弃,释放空间以便写更多的数据。
管道的结构
**在Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。
过将两个file 结构指向同一个临时的VFS 索引节点,而这个VFS引节点又指向一个物理页面而实现的。**
Java如何使用管道通讯
在Java的JDK中提供了4个类来使线程间可以相互通信:
1)PipedInputSteam和PipedOutputStream
2)PipedReader和PipedWriter
ThreadWrite类,发送数据的线程。
import java.io.IOException;import java.io.PipedWriter;public class ThreadWrite extends Thread{ private PipedWriter out; public ThreadWrite(PipedWriter out){ super(); this.out = out; } @Override public void run(){ try{ System.out.println("write:"); for(int i=0;i<300;i++){ String outData = ""+(i+1); out.write(outData); System.out.print(outData); } System.out.println(); out.close(); }catch (IOException e){ e.printStackTrace(); } }}
ThreadRead类,读取数据的线程。
import java.io.IOException;import java.io.PipedReader;public class ThreadRead extends Thread{ private PipedReader input; public ThreadRead(PipedReader input){ super(); this.input = input; } @Override public void run(){ try{ System.out.println("read:"); char[] byteArray = new char[100]; int readLength = input.read(byteArray); while (readLength!=-1){ String newData = new String(byteArray,0,readLength); System.out.print(newData); readLength = input.read(byteArray); } System.out.println(); input.close(); }catch (IOException e){ e.printStackTrace(); } }}
测试类:
import java.io.PipedReader;import java.io.PipedWriter;public class RunTest { public static void main(String[] args){ try{ PipedReader pipedReader = new PipedReader(); PipedWriter pipedWriter = new PipedWriter(); //inputStream.connect(outputStream); pipedWriter.connect(pipedReader); //将pipedWriter和pipeRead通过connect相连 ThreadRead threadRead = new ThreadRead(pipedReader); //启动读线程 threadRead.start(); Thread.sleep(2000); ThreadWrite threadWrite = new ThreadWrite(pipedWriter); //启动写线程 threadWrite.start(); }catch (IOException e){ e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }}
- Java使用管道实现进程间通讯
- Java使用管道实现进程间通讯
- 管道实现进程间通讯
- 管道实现进程间通讯
- 管道实现进程间通讯
- 管道实现进程间通讯 (zz)
- 管道实现进程间通讯 、WaitNamedPipe
- 管道实现进程间通讯 、WaitNamedPipe
- 利用命名管道实现进程间通讯
- Delphi 使用管道进程间通讯
- 进程间通讯--管道
- 进程间通讯:管道
- 进程间通讯--管道
- Linux进程间通讯--管道(有名管道
- 进程间通讯---匿名管道
- linux进程间通讯--管道
- Linux-进程间通讯-管道
- 进程间通讯-有名管道
- SpringMVC
- Java JVM 3:垃圾收集算法
- 递推递归-D-汉诺塔系列1
- Java编程思想-02一切都是对象
- appframework简单布局
- Java使用管道实现进程间通讯
- java 什么是多态?多态的三种表现形式?什么是向上转型和向下转型?多态的利和弊?
- GitHub 的分支创建与合并
- 静态成员变量与静态成员函数
- JavaWeb前端知识-JavaScript进阶
- 跨域问题
- 2017年院赛G题 忠诚
- JS中对于form表单提交时验证form的onsubmit函数与submit类型按钮的onclick函数
- Cadence icfb 的基本操作