Java学习笔记 - Java 使用管道实现半双工通信

Java 管道原理

在这里插入图片描述
如上图 : 线程A 将数据写入到 管道中, 这个管道是一个缓冲区, 我的理解是就像是一个文件, 线程A 将数据写入到这个文件(管道)中, 而线程 B 从这个文件中读取数据 ,这样就实现了进程间的通信

Java 管道的一些特点

  1. 管道流是单向的, 只能由 输出流 -> 管道 -> 输入流

  2. 管道中的数据一旦被读取就会从管道中丢弃, 释放空间以便于写入更多的数据

  3. 如果在向管道缓冲区的数据已经满的时候, 写入数据的 Write 方法会自动被阻塞, 等待缓冲区数据被读取有空闲的空间的时候才会继续向管道中写入数据, 同样的, 从管道读取数据的时候 当管道为空的时候,读取数据的read方法也会被阻塞,等待管道中有数据的时候才会继续读取

  4. 管道的输入输出流 任何一个提前关闭 都不会影响到另外一个流,

  5. 注意:管道输出流输出结束后一定要关闭输出流,因为只有关闭输出流之后,对端输入流read()才能返回null,如果没有关闭输出流
    会报错 : java.io.IOException: Write end dead

Java 管道的Demo

package com.wangt.juc.thread.communication;

import java.io.*;

/**
 * @author 王天赐
 * @create 2019-11-02 15:53
 */
public class ThreadCommunicationByPipe {



    // 读线程
    public static class ReadThread implements Runnable{

        private PipedInputStream pis = null;
        private String lines = "";

        // 获取 管道输入流
        public PipedInputStream getPis(){
            pis = new PipedInputStream();
            return pis;
        }

        @Override
        public void run() {

            // 将管道输入流转换为缓冲流
            BufferedReader br = new BufferedReader(new InputStreamReader(pis));
            System.out.println("Read 线程开启 开始读入数据.... ");
            try {
                while((lines = br.readLine()) != null){
                    // 打印输入的数据
                    System.out.println("read : " + lines);
                }
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 写线程
    public static class WriteThread implements Runnable{

        private PipedOutputStream pos = null;

        // 获取管道输出流
        public PipedOutputStream getPos() {
            pos = new PipedOutputStream();
            return pos;
        }

        @Override
        public void run() {
            long time = System.currentTimeMillis();
            System.out.println("Write 线程开启 开始写数据.... ");
            PrintStream ps = new PrintStream(pos);
            for (int i = 0; i < 10; i++) {
                ps.println("假面骑士 " + i + " 号");
                ps.flush();
            }
            // 注意 : 这里不关闭 会报错 : java.io.IOException: Write end dead
            ps.close();
        }
    }

    public static void main(String[] args) throws IOException {

        WriteThread write = new WriteThread();
        ReadThread read = new ReadThread();

        // 连接 输入和输出管道流
        // 注意 : 管道只能是单向通信, 如果想双向 需要创建两个管道
        write.getPos().connect(read.getPis());
        // 开启线程
        new Thread(write).start();
        new Thread(read).start();

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兀坐晴窗独饮茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值