说明
Java中的 Pipe
管道是用于 一个虚拟机中的线程之间通信
注意:
- 一个虚拟机中,也就是一个java程序
- 不能用于进程之间通信,也就是不能是多个java程序
分类
Java中 Pipe
分为以下类型:
- 字符流
PipedWriter
:字符输出流,发送消息PipedReader
:字符输入流,接收消息
- 字节流
PipedOutputStream
:字节输出流,发送消息PipedInputStream
:字节输入流,接收消息
使用
Pipe
管道流的使用方式,与java其他流几乎相同
连接管道
Pipe 管道输出流 可以连接 Pipe 管道输入流
有两种方式:
- 使用
connect()
方法 - 通过构造方法
使用 connect()
方法
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
// 通过输出流的 connect() 连接输入流
pos.connect(pis);
// 通过输入流的 connect() 连接输出流
// 本质还是调用 输出流的 connect()
pis.connect(pos);
通过构造方法
PipedInputStream pis = new PipedInputStream();
// 通过构造方法
PipedOutputStream pos = new PipedOutputStream(pis);
发送数据
在一个线程中,通过 Pipe
管道输出流的 write()
方法发送数据
接收数据
在另一个线程中,通过 Pipe
管道输入流的 read()
方法接收数据
注意
由于
Pipe
管道流是用于 一个虚拟机中的线程之间通信,所以,Pipe
管道输出流 和Pipe
管道输入流 要在 不同的线程中(在一个虚拟机中)不要在 一个线程 中 同时 使用管道输入流和管道输出流,会造成 死锁
例子
发送数据线程
package 管道;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
public class SendThread extends Thread{
PipedWriter writer = new PipedWriter();
public void connect(PipedReader pr) throws IOException {
writer.connect(pr);
}
@Override
public void run() {
try {
/*
由于接收数据时,使用 BufferedReader 的 readLine() 读取一行方法
所以末尾有 \n 换行符,表示发送一行数据
*/
writer.write("李雷\n");
Thread.sleep(100);
writer.write("韩梅梅\n");
Thread.sleep(100);
writer.write("lucy\n");
Thread.sleep(100);
writer.write("lili\n");
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
try {
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public PipedWriter getWriter() {
return writer;
}
}
接收数据线程
package 管道;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PipedReader;
public class ReceiveThread extends Thread{
PipedReader reader = new PipedReader();
BufferedReader br = new BufferedReader(reader);
@Override
public void run() {
while (true){
try {
/*
使用 readLine() 方法读取一行数据,所以发送数据时,末尾要有 \n
*/
String s = br.readLine();
/*
管道输出流关闭后,这里接收到数据都是null
所以,当接收到null时,就说明管道输出流关闭,就退出接收数据
*/
if(s==null){
break;
}
System.out.println(this.getClass().getSimpleName()+":"+s);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
br.close();
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public PipedReader getReader() {
return reader;
}
}
启动类
package 管道;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
SendThread sendThread = new SendThread();
ReceiveThread receiveThread = new ReceiveThread();
try {
// 连接管道
sendThread.connect(receiveThread.getReader());
} catch (IOException e) {
e.printStackTrace();
}
sendThread.start();
receiveThread.start();
}
}
执行结果:
ReceiveThread:李雷
ReceiveThread:韩梅梅
ReceiveThread:lucy
ReceiveThread:lili
参考:
https://blog.csdn.net/weixin_44671737/article/details/113902971
https://blog.csdn.net/weixin_34154352/article/details/114469098