Introduction of PipedWriter
PipedWriter is a character pipeline output stream, inherited from Writer. Its function is similar to that of PipedOutputStream. PipedWriter is combined with PipedReader to realize the function of similar pipeline. In multi-threaded environment, a thread writes data using PipedWriter and transfers data through pipeline to the internal buffer of character input stream at the other end of the pipeline (actually through the current character pipeline output). The receiving method of stream-bound character pipeline input stream object sink stores data into the internal character buffer of the character input stream, and other threads read the character data of the internal buffer to realize inter-thread communication.
2. PipedWriter class member variables
package java.io; public class PipedWriter extends Writer { /** Pipebound character input stream objects**/ private PipedReader sink; /* * The state of the current pipeline character output stream, independent of the state of the character input stream at the other end of the pipeline */ private boolean closed = false; }
3. PipedWriter Source Code Analysis
1-constructor
/** * Constructor that calls connect to establish a connection between the current object and the specified character pipeline input stream object */ public PipedWriter(PipedReader snk) throws IOException { connect(snk); } /** * Constructor, empty implementation, not yet connected to the pipeline's character input stream, must be established before use, whether PipedReader or PipeReader, the pipeline data receiver * Or is it PipedWriter on the data writer calling connect to establish a connection? */ public PipedWriter() { }
PipedWriter's constructor logic is very simple. One constructor does nothing but create an object without a pipeline connection. The other constructor calls connect to create a pipeline connection with the specified character pipeline input stream object at the same time of instantiation. After that, PipedWriter mainly operates pipeline data based on the specified pipeline input stream object.
2 - void write(int c) method - write a single character
public void write(int c) throws IOException { if (sink == null) { throw new IOException("Pipe not connected"); } sink.receive(c); }
The method logic is very simple, that is to say, at the beginning, the sink of the input stream object of the receiving end character pipeline binded by the pipeline is blanked. If it is not blank, its receive method is called to receive the written single character c. The internal method logic of receive can refer to PipedReader's analysis of the receive method in the previous part.
3 - Other Membership Method
/** * Connect the specified pipeline input stream object snk for the current pipeline output stream object, and throw if the connection with other character pipeline input stream has been established before the current pipeline output stream. * IOException abnormal */ 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; } /** * Writes len characters of the specified character array cbuf from the off position to the pipeline-bound character pipeline input stream object internal buffer * If a thread is reading the internal buffer byte data of the connected character pipeline input stream, an IO exception will be thrown if the current thread is suspended. */ public void write(char cbuf[], int off, int len) throws IOException { //Pipebound character pipeline input stream object is empty if (sink == null) { throw new IOException("Pipe not connected"); } /** Verify the start position parameter off of the character array**/ else if ((off | len | (off + len) | (cbuf.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } //Write character array data to the internal buffer of the pipe-bound character input stream sink.receive(cbuf, off, len); } /** * Refreshing the pipeline output stream is mainly realized by waking up the pipeline input stream waiting for the read thread to read the data. */ public synchronized void flush() throws IOException { if (sink != null) { if (sink.closedByReader || closed) { throw new IOException("Pipe closed"); } synchronized (sink) { sink.notifyAll(); } } } /** * Closing the current pipeline output stream object and releasing system resources related to it is actually calling the reveivedLast method of the bound pipeline input stream object sink * Update the sink pipe write end state member variable closedByWriter and wake up other waiting threads */ public void close() throws IOException { closed = true; if (sink != null) { sink.receivedLast(); } }