Java~通过管道进行线程间通信: (字节流与字符流)

    科技2026-03-04  6

    文章目录

    字节流代码演示 字符流代码演示

    在Java语言中提供了各种各样的输人/输出流Stream,使我们能够很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据。一个线程发送数据到输出管道,另一个线程从输人管道中读数据。通过使用管道,实现不同线程间的通信,而无须借助于类似临时文件之类的东西。在Java的JDK中提供了4个类来使线程间可以进行通信: 字节流: PipedInputStream和PipedOutputStream 字符流: PipedReader和 PipedWriter PS: 无论使用哪一对流, 都要使俩个流(输入与输出)建立连接, 这样才可以将数据进行输出与输入

    字节流

    PipedInputStream和PipedOutputStream

    代码演示

    写数据 public class WriteStreamDate { public void writeDate(PipedOutputStream pipedOutputStream) { System.out.println(Thread.currentThread().getName() + " 开始向管道中写东西"); try { for (char ch = 'a'; ch <= 'z'; ch++) { String date = ch + " "; pipedOutputStream.write(date.getBytes()); } pipedOutputStream.flush(); pipedOutputStream.close(); System.out.println(Thread.currentThread().getName() + " 写数据完毕"); } catch (IOException e) { e.printStackTrace(); } } } 读数据 public class ReadStreamDate { public void readDate(PipedInputStream pipedInputStream) { System.out.println(Thread.currentThread().getName() + " 开始从管道中读数据"); byte[] buffer = new byte[20]; int len = -1; try { while ((len = (pipedInputStream.read(buffer))) != -1) { String date = new String(buffer, 0, len); System.out.print(date); } System.out.println(); pipedInputStream.close(); System.out.println(Thread.currentThread().getName() + " 读完毕"); } catch (IOException e) { e.printStackTrace(); } } } 运行 public class Run { public static void main(String[] args) throws IOException, InterruptedException { //创建流对象 PipedInputStream pipedInputStream = new PipedInputStream(); PipedOutputStream pipedOutputStream = new PipedOutputStream(); //建立连接 pipedInputStream.connect(pipedOutputStream); //或者 //pipedOutputStream.connect(pipedInputStream); WriteStreamDate writeStreamDate = new WriteStreamDate(); ReadStreamDate readStreamDate = new ReadStreamDate(); //创建俩个线程 Thread a = new Thread("A") { @Override public void run() { writeStreamDate.writeDate(pipedOutputStream); } }; Thread b = new Thread("B") { @Override public void run() { readStreamDate.readDate(pipedInputStream); } }; b.start(); Thread.sleep(100); a.start(); Thread.sleep(100); } } 运行结果 上述代码首先是读取线程启动,由于当时没有数据被写人,所以线程阻塞在len = (pipedInputStream.read(buffer);代码中,直到有数据被写入并且执行colse方法,才继续向下运行。当然如果是写线程先启动就没这个问题.

    字符流

    PipedReader和 PipedWriter

    代码演示

    写数据 public class WriteDate { public void write(PipedWriter pipedWriter) { System.out.println(Thread.currentThread().getName() + " 开始写数据"); StringBuilder date = new StringBuilder(); try { for (char ch = 'a'; ch <= 'g'; ch++) { date.append(ch); pipedWriter.write(date.toString() + " "); } pipedWriter.flush(); pipedWriter.close(); System.out.println(Thread.currentThread().getName() + " 写数据完毕"); } catch (IOException e) { e.printStackTrace(); } } } 读数据 public class ReadDate { public void read(PipedReader pipedReader) { System.out.println(Thread.currentThread().getName() + " 开始读数据"); char[] buffer = new char[20]; int len = -1; try { while ((len = pipedReader.read(buffer)) != -1) { String date = new String(buffer, 0, len); System.out.println(date); } pipedReader.close(); System.out.println(Thread.currentThread().getName() + " 读数据完毕"); } catch (IOException e) { e.printStackTrace(); } } } 运行类 public class Run2 { public static void main(String[] args) throws IOException, InterruptedException { //创建流对象建立连接 PipedReader pipedReader = new PipedReader(); PipedWriter pipedWriter = new PipedWriter(); pipedReader.connect(pipedWriter); // ReadDate readDate = new ReadDate(); WriteDate writeDate = new WriteDate(); //创建线程 Thread a = new Thread("A") { @Override public void run() { writeDate.write(pipedWriter); } }; Thread b = new Thread("B") { @Override public void run() { readDate.read(pipedReader); } }; // a.start(); Thread.sleep(100); b.start(); Thread.sleep(100); } } 执行结果 这个代码如果是读线程提前, 问题和字节流是一样的, 依旧会阻塞在len = (pipedInputStream.read(buffer)
    Processed: 0.012, SQL: 9