• Java IO(八) PipedInputStream 和 PipedOutputStream


    Java IO(八) PipedInputStream 和 PipedOutputStream

    一、介绍

     PipedInputStream 和 PipedOutputStream 是管道输入流和管道输出流。它们的作用就是让多线程通过管道进行线程间的通讯。在使用管道通讯时,必须 PipedInputStream 和 PipedOutputStream 配套使用。

    使用管道通信时,大致的流程是:我们在线程A中向 PipedOutputStream 中写入数据,这些数据会自动的发送到与 PipedOutputStream 对应的 PipedInputStream 中,进而存储在 PipedInputStream 的缓冲中;此时,线程B通过读取 PipedInputStream 中的数据,这样就可以实现,线程A和线程B的通信。

    不建议单个线程使用这两个对象,因为它可能会使线程死锁。

    二、构造方法

    (一)、PipedInputStream

    (二)、PipedOutputStream

    三、常用API

    (一)、PipedInputStream

    (二)、PipedOutputStream

    四、实例

    多线程通过 PipedInputStream 和 PipedOutputStream 进行线程间同通讯,下面例子分别定义三个类:PipedDemo(主线程main类),PipedSender(发送者对象)、PipedReceiver(接收者对象)。实例中只贴出主要代码。

    注意点:

    管道输入流 PipedInputStream 与管道输出流 PipedOutputStream 建立连接

    建立连接一般使用 connect() 方法连接或在创建输入流对象时,传递连接该管道的输出流对象。

    connect() ,如:out.connect(in) 和 in.connect(out) 是等价的,开发时只能选择其中的一个而不能两个 connect 同时调用,否则会抛出 java.io.IOException: Already connected 异常。

    创建流对象,如:PipedOutputStream out = new PipedOutputStream(in),in 为 PipedInputStream 对象,必须先实例化使用,否则会报 java.lang.NullPointerException 异常。PipedOutputStream out = new PipedOutputStream(in) 与 PipedInputStream in = new PipedInputStream(out) 是等价的,开发时传递的流对象作为参数必须实例化,然后进行传递。

    (一)、PipedSender(发送者对象)

    public class PipedSender extends Thread{
        // 定义私有PipedOutputStream  对象
        private PipedOutputStream out = new PipedOutputStream();
        
        public PipedOutputStream getOutputStream() {
            return out;
        }
            // 线程执行的方法
        @Override
        public void run() {
         //writeOne(); 
             writeMove();
        }
    
        /**
         * 写入一段短数据
         */
        private void writeOne() {
            byte[] buffer = "this is a message".getBytes();
            try {
                out.write(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 写入较长数据
         */
        public void writeMove() {
            StringBuffer sb = new StringBuffer();
            for(int i = 0;i < 100;i++) {
                sb.append("12345678790");
            }
            sb.append("abcdefghijklmnopqrstvuwxyz");
            String str = sb.toString();
            try {
                out.write(str.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }    

    (二)、PipedReceiver(接收者对象)

    public class PipedReceiver extends Thread{
        // 私有PipedInputStream 对象
        private PipedInputStream in = new PipedInputStream();
        public PipedInputStream getInputStream() {
            return in;
            
        }
        @Override
        public void run() {
            //readOne();
            readMove();
        }
        
        
        /**
         * 读取一次
         */
        public void readOne() {
            byte[] buffer = new byte[2048];
            int len = 0;
            try {
                len = in.read(buffer);
                System.out.println(new String(buffer,0,len));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
            
        }
        
        /**
         * 读取多次
         */
        private void readMove() {
            byte[] buffer = new byte[1024];
            int len = 0;
            try {
                while(true) {
                    len = in.read(buffer);
                    // 一值读取,直到结束
                    if(len == -1)
                        break;
                    System.out.println(new String(buffer,0,len));
                }
            }catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    (三)、PipedDemo(main方法类)

    public class PipedDemo {
    
        public static void main(String[] args) {
            PipedSender sender = new PipedSender();
            PipedReceiver receiver = new PipedReceiver();
            
            PipedOutputStream out = sender.getOutputStream();
            PipedInputStream in = receiver.getInputStream();
    try { // 下面两条语句是一样的,但只能允许存在一条语句 //in.connect(out); out.connect(in);        // 分别开启两个线程 sender.start(); receiver.start(); } catch (IOException e) { e.printStackTrace(); } } }
  • 相关阅读:
    mysql进阶语句优化---day40
    pymysql基本语法,sql注入攻击,python操作pymysql,数据库导入导出及恢复数据---day38
    单表查询,多表查询,子查询---day37
    mysql-数据类型,类型约束,联合唯一约束,表与表之间的关系,存储引擎---day36
    mysql安装及增删改查操作---day35
    死锁,互斥锁,递归锁,线程事件Event,线程队列Queue,进程池和线程池,回调函数,协程的使用,协程的例子---day33
    进程之间共享数据Manager,线程相关使用Thread,用类定义线程,守护线程setDaemon,线程锁Lock,线程信号量Semaphore---day32
    Docker部署go-fastdfs
    Docker部署gitlab
    Docker部署hasura
  • 原文地址:https://www.cnblogs.com/lingq/p/12920208.html
Copyright © 2020-2023  润新知