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

  • 在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)
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值