Java 线程间通信在很长一段时间以来一直是热门的面试问题。 在 JDK 1.5 版本中,ExecutorService和BlockingQueue带来了另一种更有效的实现方式,但管道流方法也值得了解,在某些情况下可能有用。
Table of contentsWhat are piped streamsPipedReader and PipedWriterJava inter-thread communication exampleSummary
什么是管道流
管道流就像真实的管道一样。 您可以使用某些方法将事物一端放入管道中。 然后,您可以使用其他方法从另一端的管道流中收到相同的信息。
它们以 FIFO 顺序的先入先出的方式出现,就像从实际的管道中一样。
PipedReader和PipedWriter
PipedReader是Reader类的扩展,用于读取字符流。 它的read()方法读取连接的PipedWriter的流。 同样,PipedWriter 是Writer类的扩展,它执行Reader类所收缩的所有工作。
可以通过以下两种方法将作家连接到读者:
- 使用构造器
PipedWriter(PipedReader pr) - 使用
connect(PipedReader pr)方法
通过上述任何一种方式连接后,任何线程都可以使用write(....)方法在流中写入数据,并且数据将可供读取器使用,并且可以使用read()方法进行读取。
Java 线程间通信示例
下面给出的 Java 程序创建两个线程。 一个线程负责写入流,第二个线程仅读取数据以在控制台中打印它们。
public class PipeReaderThread implements Runnable{PipedReader pr;String name = null;public PipeReaderThread(String name, PipedReader pr){this.name = name;this.pr = pr;}public void run(){try {// continuously read data from stream and print it in consolewhile (true) {char c = (char) pr.read(); // read a charif (c != -1) { // check for -1 indicating end of fileSystem.out.print(c);}}} catch (Exception e) {System.out.println(" PipeThread Exception: " + e);}}}
public class PipeWriterThread implements Runnable{PipedWriter pw;String name = null;public PipeWriterThread(String name, PipedWriter pw) {this.name = name;this.pw = pw;}public void run() {try {while (true) {// Write some data after every two secondspw.write("Testing data written...n");pw.flush();Thread.sleep(2000);}} catch (Exception e) {System.out.println(" PipeThread Exception: " + e);}}}
package multiThread;import java.io.*;public class PipedCommunicationTest{public static void main(String[] args){new PipedCommunicationTest();}public PipedCommunicationTest(){try{// Create writer and reader instancesPipedReader pr = new PipedReader();PipedWriter pw = new PipedWriter();// Connect the writer with readerpw.connect(pr);// Create one writer thread and one reader threadThread thread1 = new Thread(new PipeReaderThread("ReaderThread", pr));Thread thread2 = new Thread(new PipeWriterThread("WriterThread", pw));// start both threadsthread1.start();thread2.start();}catch (Exception e){System.out.println("PipeThread Exception: " + e);}}}
程序输出:
Testing data written...Testing data written...Testing data written...
总结
- 您必须先创建某种类型的读取器并将其连接,然后才能写入管道。 换句话说,两个端必须存在并且已经连接,以使写入端正常工作。
- 完成写入管道后,您将无法切换到最初未连接管道的其他读取器。
- 如果关闭阅读器,则无法从管道中读回。 但是,您可以成功关闭写入端,并且仍然可以从管道读取数据。
- 如果写入管道的线程结束,则无法从管道读回。
学习愉快!
