文档章节

Java IO类库之PipedWriter

 老韭菜
发布于 08/15 14:22
字数 1030
阅读 0
收藏 0

一、PipedWriter介绍

    PipedWriter是字符管道输出流,继承自Writer,功能与PipedOutputStream类似,通过与PipedReader组合使用实现类似管道的功能,在多线程环境下,一个线程使用PipedWriter写入数据,通过管道将数据传递到管道另一端的字符输入流内部缓冲区(实际是通过当前字符管道输出流绑定的字符管道输入流对象sink的receive方法将数据存储到字符输入流的内部字符缓冲区实现的),其他线程去读该内部缓冲区的字符数据,实现线程间通信。

二、PipedWriter类成员变量

package java.io;

public class PipedWriter extends Writer {

    /** 管道绑定的字符输入流对象 **/
    private PipedReader sink;

    /* 
     * 当前管道字符输出流的状态,独立于管道另一端字符输入流的状态
     */
    private boolean closed = false;

}

三、PipedWriter源码分析

1 - 构造函数

   /**
    * 构造函数,调用connect为当前对象与指定字符管道输入流对象建立连接
    */
   public PipedWriter(PipedReader snk)  throws IOException {
        connect(snk);
    }

    /**
     * 构造函数,空实现,还没与管道的字符输入流建立连接,在使用之前必须先建立连接无论是管道数据接收端PipedReader还是
     * 还是数据写入端PipedWriter调用connect建立连接
     */
    public PipedWriter() {
    }

    PipedWriter的构造函数逻辑非常简单,两种构造函数一种什么都没做只是创建一个未建立管道连接的对象,另一个构造函数在实例化的同时调用connect创建了与指定字符管道输入流对象的管道连接,之后PipedWriter主要是基于这个指定的管道输入流对象操作管道数据。

2 - void write(int c)方法 - 写入单个字符

    public void write(int c)  throws IOException {
        if (sink == null) {
            throw new IOException("Pipe not connected");
        }
        sink.receive(c);
    }

    方法逻辑很简单就是在开头做了管道绑定的接收端字符管道输入流对象sink的判空,若不为空则调用它的receive方法接收写入的单个字符c,receive的内部方法逻辑可参照上篇PipedReader对于receive方法的解析

3 - 其他成员方法

    /**
     * 为当前管道输出流对象连接指定的管道输入流对象snk,若当前管道输出流之前已经建立与其他字符管道输入流的连接则抛出
     * IOException异常
     */
    public synchronized void connect(PipedReader snk) throws IOException {
        if (snk == null) {
            throw new NullPointerException();
        } else if (sink != null || snk.connected) {
            throw new IOException("Already connected");
        } else if (snk.closedByReader || closed) {
            throw new IOException("Pipe closed");
        }

        sink = snk;
        snk.in = -1;
        snk.out = 0;
        snk.connected = true;
    }


    /**
     * 将指定字符数组cbuf从off位置开始len个字符写入管道绑定的字符管道输入流对象内部缓冲区中
     * 如果一个线程正在读取连接的字符管道输入流内部缓冲区字节数据,这时候当前线程挂掉那么会抛出一个IO异常
     */
    public void write(char cbuf[], int off, int len) throws IOException {
        //管道绑定的字符管道输入流对象为空
        if (sink == null) {
            throw new IOException("Pipe not connected");
        } 
        /** 校验字符数组起始位置参数off **/
        else if ((off | len | (off + len) | (cbuf.length - (off + len))) < 0) {
            throw new IndexOutOfBoundsException();
        }
        //将字符数组数据写入管道绑定的字符输入流内部缓冲区
        sink.receive(cbuf, off, len);
    }

    /**
     * 刷新管道输出流,主要是通过唤醒管道输入流等待读取线程读取数据实现刷新的。
     */
    public synchronized void flush() throws IOException {
        if (sink != null) {
            if (sink.closedByReader || closed) {
                throw new IOException("Pipe closed");
            }
            synchronized (sink) {
                sink.notifyAll();
            }
        }
    }

    /**
     * 关闭当前管道输出流对象,释放与此有关的系统资源,实际是调用绑定的管道输入流对象sink的reveivedLast方法
     * 更新sink管道写入端状态成员变量closedByWriter并唤醒其他等待线程
     */
    public void close()  throws IOException {
        closed = true;
        if (sink != null) {
            sink.receivedLast();
        }
    }

 

© 著作权归作者所有

共有 人打赏支持
粉丝 12
博文 64
码字总数 107681
作品 0
杭州
后端工程师
私信 提问
Java_io体系之PipedWriter、PipedReader

Javaio体系之PipedWriter、PipedReader简介、走进源码及示例——14 这两个类必须配套来使用,一般是用于两个线程之间的通信,想了一下其实就是一个线程往buf数组写,另一个线程从这个buf数组...

z_jordon
2015/04/28
0
0
InputStream和Reader的区别

java.io.Reader 和 java.io.InputStream 组成了Java 输入类。Reader 用于读入16位字符,也就是Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。 Reader支持16位的Uni...

SibylY
2013/08/14
0
0
Java多线程学习(五)线程间通信知识点补充

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
04/16
0
0
有效选择七个关于Java的JSON开源类库

April 4, 2014 By Constantin Marian Alin 翻译:无若 (英语原文:http://www.developer.com/lang/jscript/top-7-open-source-json-binding-providers-available-today.html) 简介 JSON是J......

无若
2014/04/19
0
1
《Kotin 极简教程》第15章 Kotlin 文件IO操作、正则表达式与多线程

第15章 Kotlin 文件IO操作与多线程 《Kotlin极简教程》正式上架: 点击这里 > 去京东商城购买阅读 点击这里 > 去天猫商城购买阅读 非常感谢您亲爱的读者,大家请多支持!!!有任何问题,欢迎...

程序员诗人
2017/07/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sed, awk 练习

1. sed打印某行到某行之间的内容 2. sed 转换大小写 将单词首字母转化大写 将所有小写转化大写 3. sed 在某一行最后面添加一个数字 4. 删除某行到最后一行 解析: {:a;N;$!ba;d} :a : 是...

Fc丶
今天
2
0
babel6升级到7,jest-babel报错:Requires Babel "^7.0.0-0", but was loaded with "6.26.3".

自从将前端环境更新到babel7,jest-babel之前是基于babel6的,执行时候就会报:Requires Babel "^7.0.0-0", but was loaded with "6.26.3". 很烦,因为连续帮好几台电脑修复这个问题,所以记...

曾建凯
今天
1
0
探索802.11ax

802.11ax承诺在真实条件下改善峰值性能和最差情况。 如何改善今天的Wi-Fi? 在决定如何改进当前版本以外的Wi-Fi时,802.11ac,IEEE和Wi-Fi联盟调查了Wi-Fi部署和行为,以确定更广泛使用的障碍...

linuxprobe16
今天
2
0
使用linux将64G的SDCARD格式化为FAT32

一、命令如下: sudo fdisk -lsudo mkfs.vfat /dev/sda -Isudo fdisk /dev/sda Welcome to fdisk (util-linux 2.29.2). Changes will remain in memory only, until you decide to wri......

mbzhong
今天
4
0
深入理解Plasma(四):Plasma Cash

这一系列文章将围绕以太坊的二层扩容框架,介绍其基本运行原理,具体操作细节,安全性讨论以及未来研究方向等。本篇文章主要介绍在 Plasma 框架下的项目 Plasma Cash。 深入理解Plasma(1):...

HiBlock
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部