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