本文内容部分引自《Java多线程编程核心技术》,感谢作者!!!
代码地址:https://github.com/xianzhixianzhixian/thread.git
相关知识讲解
1、Java中提供了很多输入/输出流Stream,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据。一个线程发送数据到输入管道,另一个线程从输入管道中读取数据。通过使用管道,可以实现不同线程间的通信,无需借助于类似临时文件之类的东西。
2、使用PipedInputStream和PipedOutputStream可以实现线程间通信:PipedInputStream用于从管道中读取字节流数据,PipedOutputStream用于向管道中写入字节流数据。
3、使用PipedInputStream中的connect(PipedOutputStream实例)或PipedOutputStream中的connect(PipedInputStream实例)来连接管道从而进行读写字节流数据,两者不可同时使用,否则会报java.io.IOException: Already connected错误。
代码示例
ReadData.java
/**
* 使用PipedInputStream和PipedOutputStream实现线程间通信
* @author: xianzhixianzhixian
* @date: 2019-01-02 19:39
*/
public class ReadData {
public void readMethod(PipedInputStream input){
try {
System.out.println("read:");
byte[] byteArray = new byte[20];
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 (Exception e) {
e.printStackTrace();
}
}
}
WriteData.java
/**
* 使用PipedInputStream和PipedOutputStream实现线程间通信
* @author: xianzhixianzhixian
* @date: 2019-01-02 19:36
*/
public class WriteData {
public void writeMethod(PipedOutputStream out){
try {
System.out.println("write:");
for (int i = 0; i < 300; i++) {
String outData = "" + (i + 1);
out.write(outData.getBytes());
System.out.print(outData);
}
System.out.println();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadRead.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-02 19:45
*/
public class ThreadRead extends Thread {
private ReadData read;
private PipedInputStream input;
public ThreadRead(ReadData read, PipedInputStream input) {
this.read = read;
this.input = input;
}
@Override
public void run() {
super.run();
read.readMethod(input);
}
}
ThreadWrite.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-02 19:43
*/
public class ThreadWrite extends Thread {
private WriteData write;
private PipedOutputStream out;
public ThreadWrite(WriteData write, PipedOutputStream out) {
this.write = write;
this.out = out;
}
@Override
public void run() {
super.run();
write.writeMethod(out);
}
}
Run.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-02 19:46
*/
public class Run {
public static void main(String[] args) {
try {
WriteData writeData = new WriteData();
ReadData readData = new ReadData();
PipedInputStream inputStream = new PipedInputStream();
PipedOutputStream outputStream = new PipedOutputStream();
inputStream.connect(outputStream);
//outputStream.connect(inputStream);
/**
* 在代码中首先启动的是threadRead,由于当时没有数据被写入,所以线程阻塞在
* int readLength=input.read(byteArray);直到有数据写入后,才继续向下运行。
*/
ThreadRead threadRead = new ThreadRead(readData, inputStream);
threadRead.start();
Thread.sleep(2000);
ThreadWrite threadWrite = new ThreadWrite(writeData, outputStream);
threadWrite.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:注意Run.java中先调用的是threadRead.start(),但是打印结果的时候还是先write后read的,因为虽然在代码中首先启动的是threadRead,由于当时没有数据被写入,所以线程阻塞在int readLength=input.read(byteArray);直到有数据写入后,才继续向下运行